1

I can pass in a time to my widget, but my widget is supposed to be instantiating the time in itself, not receiving a DateTime from a parent widget.

Mary
  • 18,347
  • 23
  • 59
  • 76

3 Answers3

2

The clock package: https://pub.dartlang.org/documentation/clock/latest/clock/clock-library.html lets you inject a fake clock into the test.

Mary
  • 18,347
  • 23
  • 59
  • 76
2
extension CustomizableDateTime on DateTime {
  static DateTime customTime;
  static DateTime get current {
    if (customTime != null)
      return customTime;
    else
      return DateTime.now();
  }
}

Just use CustomizableDateTime.current in the production code. You can modify the returned value in tests like that: CustomizableDateTime.customTime = DateTime.parse("1969-07-20 20:18:04");. There is no need to use third party libraries.

Adam Smaka
  • 5,977
  • 3
  • 50
  • 55
  • Since it's relying on a static variable it can add hidden dependencies between tests. While running in parallel if one test changes the mock value and then it get's changed immediately by another one, it's going to fail the test. – Abdur Rafay Saleem Jul 31 '21 at 00:18
2

As Mary said, a very neat way is to use the clock package, which is maintained by the Dart team.

Normal usage:

import 'package:clock/clock.dart';

void main() {
  // prints current date and time
  print(clock.now());
}

Overriding the current time:

import 'package:clock/clock.dart';

void main() {
  withClock(
    Clock.fixed(DateTime(2000)),
    () {
      // always prints 2000-01-01 00:00:00.
      print(clock.now());
    },
  );
}

I wrote about this in more detail on my blog.

Just note that for widget tests, you need to wrap pumpWidget, pump and expect in the withClock callback - only wrapping pumpWidget does not work.

Eray Erdin
  • 2,633
  • 1
  • 32
  • 66
Iiro Krankka
  • 4,959
  • 5
  • 38
  • 42