🕰️
Flutterの自動テスト Step2 〜Unit Test DateTime.now()に依存する場合〜
Flutter 自動テスト シリーズについて
Flutterの自動テストをStep by Stepで説明しています。
一連の記事を「本」(無料)にまとめました。
今回の対象
今回もUnit Testですが、関数内でDateTime.now()を使っている場合です。
例えばこんなコードがあります。
直前の日曜日のDateTimeを取得する仕様です。
latest_sunday.dart
DateTime getLatestSunday() {
final today = DateTime.now();
if (today.weekday == DateTime.sunday) {
return DateTime(today.year, today.month, today.day);
}
return DateTime(today.year, today.month, today.day - today.weekday);
}
課題: 実行時間によって結果が変わってしまう
このコードをテストしようとすると DateTime.now()
が実行時間によって動作が変わるってしまいます。
latest_sunday_test.dart
void main() {
test('直前の日曜日は2023-11-05', () {
final latestSunday = getLatestSunday();
expect(latestSunday, DateTime(2023, 11, 5));
});
}
参考にカレンダーを貼っておきます。
このテストは実行時間が2023年11月05日〜2023年11月11日の間なら成功しますが、
それ以外の日に失敗してしまいます。
「今」を固定する
DateTime.now()で取得する日時をテスト実行中に固定することで解決します。
必要なライブラリをインストール
まずはclockとfakeAsyncをインストール
flutter pub add clock
flutter pub add fake_async --dev
DateTime.now()をclock.now()に置き換える
テスト対象のコードを書き換えます。
latest_sunday.dart
import 'package:clock/clock.dart';
DateTime getLatestSunday() {
final today = clock.now();
if (today.weekday == DateTime.sunday) {
return DateTime(today.year, today.month, today.day);
}
return DateTime(today.year, today.month, today.day - today.weekday);
}
テストコードでnowを固定する
latest_sunday_test.dart
void main() {
test('2023-11-8の直前の日曜日は2023-11-05', () {
fakeAsync(initialTime: DateTime(2023, 11, 8), (_) {
expect(getLatestSunday(), DateTime(2023, 11, 5));
});
});
}
このように書くことで、「今」が2023年11月8日の時のテストができるようになりました。
あとは前提条件のinitialTimeと期待値を色々試すコードを書けば完了です。
動作するコードはこちら
次の記事はこちら
最後に(宣伝)
友人と個人開発でゲーミフィケーション記録アプリ「HibaQuest」を作っています。
よければお試しください。
Discussion