Grappling with Dates in Dart

If you've ever tried testing Dart methods with internal dates, you may have noticed it can quickly become painful.
Let's consider the following method with an internal dependency on the current time.
void methodWithInternalDate() {
final today = DateTime.now();
// logic dependent on the current time
}
If we need to assume the method has a fixed time as part of our testing, then the standard approach would be to inject the required date into the method as an argument. This gets quite messy, either making it nullable
and only using it for testing, which feels like a hack
void someMethodWithDate(DateTime? time) {
final today = time ?? DateTime.now();
// code that uses today
}
or requiring the argument, but then we generate extra bloat whenever calling the method outside of tests
void someMethodWithDate(DateTime time) {
final today = time;
// code that uses today
}
Neither seem ideal, so we can use the clock package developed by the Dart team instead.
import 'package:clock/clock.dart';
void someMethodWithDate() {
final today = clock.now();
// code that uses today
}
With this in place, we can easily fix dates as needed when writing tests
test('some unit test that requires fixed time', () {
// set up
final date = DateTime.now();
final dummyTime = DateTime(date.year, date.month, date.day, 15, 0, 0);
final result = withClock(
Clock.fixed(dummyTime),
() => someClass.someMethodWithDate(),
);
});