Grappling with Dates in Dart

Grappling with Dates in Dart
Photo by Keller Chewning / Unsplash

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(),
    );
  });
Mark Sindoni Houghton

Mark Sindoni Houghton

SoonCall founder & app developer
Trento, Italy