【问题标题】:How to test code that uses DateTime.now in Flutter?如何在 Flutter 中测试使用 DateTime.now 的代码?
【发布时间】:2019-05-17 20:52:30
【问题描述】:

我有这门课:

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

我想测试它是否会在传递出生日期时产生正确的年龄。在 Flutter 中执行此操作的最佳方法是什么?


解决方案:对于那些感兴趣的人,这里是使用@Günter Zöchbauer 建议的clock 包的解决方案。

我的小部件类:

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

【问题讨论】:

    标签: flutter flutter-test


    【解决方案1】:

    正如 Günther 所说,由 Dart 团队维护的 the clock package 提供了一种非常简洁的方法来实现这一目标。

    正常使用:

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

    我更详细地写过这个on my blog

    对于小部件测试,您需要将pumpWidgetpumpexpect 包装在withClock 回调中。

    【讨论】:

    • 优秀的文章。
    【解决方案2】:

    这里提到:https://stackoverflow.com/a/63073876/2235274 在 DateTime 上实现扩展。

    extension CustomizableDateTime on DateTime {
      static DateTime _customTime;
      static DateTime get current {
        return _customTime ?? DateTime.now();
      }
    
      static set customTime(DateTime customTime) {
        _customTime = customTime;
      }
    }
    

    然后在生产代码中使用CustomizableDateTime.current。您可以像这样修改测试中的返回值:CustomizableDateTime.customTime = DateTime.parse("1969-07-20 20:18:04");。无需使用第三方库。

    【讨论】:

    • 更简洁:return customTime ?? DateTime.now();
    【解决方案3】:

    如果您使用 clock 包作为依赖于 DateTime.now() 的代码,您可以轻松地模拟它。

    我不认为没有包装 DateTime.now() 的好方法可以使用 clock 包提供的包装。

    【讨论】:

      猜你喜欢
      • 2019-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 2022-01-14
      • 2016-08-05
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多