Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test code that uses DateTime.now in Flutter?

Tags:

I have this class:

import 'package:flutter/material.dart';  class AgeText extends StatelessWidget {   final String dateOfBirth;    const AgeText({Key key, @required this.dateOfBirth}) : super(key: key);    @override   Widget build(BuildContext context) {     final age = _calculateAge();     return Text(age.toString());   }    int _calculateAge() {     final dateOfBirthDate = DateTime.parse(dateOfBirth);     final difference = DateTime.now().difference(dateOfBirthDate);     final age = difference.inDays / 365;      return age.floor();   } } 

I'd like to test that it produces the correct age when a date of birth is passed into it. What is the best way to do this in Flutter?


SOLUTION: For those interested, here's the solution using @Günter Zöchbauer's suggestion of the clock package.

My widget class:

import 'package:flutter/material.dart'; import 'package:clock/clock.dart';  class AgeText extends StatelessWidget {   final String dateOfBirth;   final Clock clock;    const AgeText({Key key, @required this.dateOfBirth, this.clock = const Clock()}) : super(key: key);    @override   Widget build(BuildContext context) {     final age = _calculateAge();     return Text(age.toString());   }    int _calculateAge() {     final dateOfBirthDate = DateTime.parse(dateOfBirth);     final difference = clock.now().difference(dateOfBirthDate);     final age = difference.inDays / 365;      return age.floor();   } } 

and my test class:

import 'package:clock/clock.dart'; import 'package:flutter/material.dart'; import 'package:flutter_app/age.dart'; import 'package:flutter_test/flutter_test.dart';  void main() {   testWidgets("shows age 30 when date of birth is 30 years ago", (WidgetTester tester) async {     final mockClock = Clock.fixed(DateTime(2000, 01, 01));     final testableWidget = MaterialApp(       home: AgeText(         dateOfBirth: "1970-01-01T00:00:00",         clock: mockClock,       ),     );      await tester.pumpWidget(testableWidget);      expect(find.text("30"), findsOneWidget);   }); } 
like image 584
Jordan Davies Avatar asked Dec 17 '18 13:12

Jordan Davies


People also ask

How do you get the date time now Flutter?

import 'package:intl/intl. dart'; DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss"); Here we are going to use DateFormat class of flutter To get the current Time in AM/PM format.


2 Answers

If you use the clock package for code depending on DateTime.now() you can easily mock it.

I don't think there is a good way without a wrapper around DateTime.now() licke the clock package provides.

like image 151
Günter Zöchbauer Avatar answered Sep 21 '22 03:09

Günter Zöchbauer


As Günther said, the clock package, maintained by the Dart team, provides a very neat way to achieve this.

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.

For widget tests, you need to wrap pumpWidget, pump and expect in the withClock callback.

like image 37
Iiro Krankka Avatar answered Sep 23 '22 03:09

Iiro Krankka