対象者
- Flutterの非同期処理やストリームのテストに関心があるエンジニア
- プロジェクトでFlutterを採用しており、ストリームテストの知識を深めたいと考えている人
- 技術的なスキル向上を目指している学習意欲の高い開発者
はじめに
Flutterを使ってアプリ開発を行っているあなた。非同期処理やStreamの動作に対して不安を感じていませんか?この記事では、DartでStreamの動作を確認できるようになるべく、Streamのテストに関する基礎を分かりやすく解説し、あなたの疑問を解消します。
この記事を読むことで、Streamのテストに関する全体像がつかめ、自信を持ってテストを実装できるようになります。
Streamテストの基礎
ベース
シンプルなストリームのテスト。
Stream.fromIterable
: イテラブルからストリームを作成emitsInOrder
: ストリームが順番に要素を放出することを確認
final stream = Stream.fromIterable([
'Ready.',
'Set',
'Go!',
]);
expect(
stream,
emitsInOrder([
'Ready.',
'Set',
'Go!',
]),
);
いろんなMatcher
異なるMatcherを使ったストリームのテスト。
startsWith
: 文字列が特定の文字で始まるかを確認emitsAnyOf
: いずれかの要素を放出することを確認emitsDone
: ストリームの終了を確認
final stream = Stream.fromIterable([
'Ready.',
'Set',
'Go!',
]);
expect(
stream,
emitsInOrder([
'Ready.',
startsWith('S'),
emitsAnyOf(['Go!', 'False Start!']),
emitsDone,
]),
);
addを使ったテスト
StreamController
を使用して手動でストリームに値を追加するテスト。
StreamController
: 手動でストリームに値を追加add
: ストリームに値を追加emitsInOrder
: 順番に要素を放出することを確認
final stream = StreamController<int>();
stream.add(1);
stream.add(2);
stream.close();
expect(
stream.stream,
emitsInOrder([1, 2, emitsDone]),
);
expect を前にもかける
expect
をストリームに値を追加する前に使用するテスト。
StreamController
: 手動でストリームに値を追加expect
: テストの期待値を設定
final stream = StreamController<int>();
expect(
stream.stream,
emitsInOrder([1, 2, emitsDone]),
);
stream.add(1);
stream.add(2);
stream.close();
expectLater
expectLater
を使用して遅延ストリームのテストを行う。
StreamController
: 手動でストリームに値を追加expectLater
: 非同期でストリームの期待値を設定
expectに変えても動作する。違いが分からん(後で検証するよ、という意思表示かな)
final stream = StreamController<int>();
Future<void> addWithDelay(int value) async {
Future.delayed(const Duration(milliseconds: 10)).then((_) {
stream.add(value);
});
}
expectLater(
stream.stream,
emitsInOrder([1, 2, emitsDone]),
);
addWithDelay(1);
addWithDelay(2);
// close するまえに、データを入れるため
await Future.delayed(const Duration(milliseconds: 10));
stream.close();
処理の遅い処理 listenを使ってみる
listen
を使って遅延ストリームの処理をテストする。
StreamController
: 手動でストリームに値を追加listen
: ストリームの要素をリッスンして処理Completer
: 非同期処理の完了を待つためのオブジェクト
final stream = StreamController<int>();
Future<void> addWithDelay(int value) async {
Future.delayed(const Duration(milliseconds: 10)).then((_) {
stream.add(value);
});
}
var completer = Completer<int>();
stream.stream.listen((int data) {
completer.complete(data);
});
addWithDelay(1);
expect(await completer.future, 1);
completer = Completer<int>();
addWithDelay(2);
expect(await completer.future, 2);
stream.close();
Q&A
Q1: expect
とexpectLater
の違いは何ですか?
expect
は通常の同期的なテストに使用され、expectLater
は非同期処理を伴うテストで使用されます。今回の例ではどちらも同じように動作しますが、非同期処理を扱う際にはexpectLater
を使うのが一般的です。
Q2: emitsInOrder
とは何ですか?
emitsInOrder
は、ストリームが特定の順序で要素を放出することを確認するMatcherです。複数の要素を順番に放出するストリームの動作をテストするのに便利です。
Q3: StreamController
とは何ですか?
StreamController
は、手動でストリームにデータを追加できるコントローラーです。ストリームにデータを追加したり、ストリームを閉じたりするために使用します。
参考
まとめ
本記事では、Flutterでのストリームのテスト方法について紹介しました。基本的なストリームの操作から、さまざまなMatcherを使用したテスト方法、遅延処理を伴うストリームのテスト方法について学びました。これらの知識を活用して、非同期処理を含むアプリケーションのテストを効果的に行いましょう。