Как проверить код, который использует DateTime.now во Flutter?

У меня есть этот класс:

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();
  }
}

Я хотел бы проверить, что он дает правильный возраст, когда в него передается дата рождения. Каков наилучший способ сделать это во Флаттере?


РЕШЕНИЕ: Для тех, кто заинтересован, вот решение, использующее предложение @Günter Zöchbauer о пакете часов.

Мой класс виджетов:

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();
  }
}

и мой тестовый класс:

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);
  });
}

3 ответа

Решение

Если вы используете пакет часов для кода в зависимости от DateTime.now() Вы можете легко высмеять это.

Я не думаю, что есть хороший способ без обертки вокруг DateTime.now() облизывать clock Пакет обеспечивает.

Как сказал Гюнтер, пакет часов , поддерживаемый командой Dart, предоставляет очень удобный способ добиться этого.

Нормальное использование:

      import 'package:clock/clock.dart';

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

Отмена текущего времени:

      import 'package:clock/clock.dart';

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

Подробнее об этом я писал в своем блоге .

Для тестов виджетов нужно обернуть pumpWidget, pump а также expect в withClock Перезвоните.

Как упоминалось здесь: /questions/16095550/est-li-sposob-poddelat-datetimenow-v-teste-flutter/55449332#55449332 реализовать расширение для DateTime.

extension CustomizableDateTime on DateTime {
  static DateTime customTime;
  static DateTime get current {
    if (customTime != null)
      return customTime;
    else
      return DateTime.now();
  }
}

Тогда просто используйте CustomizableDateTime.currentв производственном коде. Вы можете изменить возвращаемое значение в таких тестах:CustomizableDateTime.customTime = DateTime.parse("1969-07-20 20:18:04");. Нет необходимости использовать сторонние библиотеки.

Другие вопросы по тегам