如何在 Flutter 中测试流中有延迟的 StreamBuilder?

apa*_*sio 2 flutter

我有一个有延迟的流。StreamBuilder 永远不会从测试中的流中获取值“foo”。如果删除延迟,则测试按预期工作。我如何告诉测试等待这个延迟?

testWidgets('stream builder', (tester) async {
  final textKey = Key('textKey');
  final stream = Observable.just('foo').delay(Duration(milliseconds: 1));

  var app = MaterialApp(
    home: StreamBuilder<String>(
      stream: stream,
      builder: (context, snapshot) => Text(
            snapshot.data ?? 'no data',
            key: textKey,
          ),
    ),
  );

  await tester.pumpWidget(app);
  await tester.pump(Duration.zero);

  Text text = tester.widget(find.byKey(textKey));
  expect(text.data, equals('foo'));
});
Run Code Online (Sandbox Code Playgroud)

这失败并出现错误

??? EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ???????????????????????????
The following TestFailure object was thrown running a test:
  Expected: 'foo'
  Actual: 'no data'
   Which: is different.
          Expected: foo
            Actual: no data
                    ^
           Differ at offset 0
Run Code Online (Sandbox Code Playgroud)

apa*_*sio 6

找到了解决办法。诀窍是将它包装起来tester.runAsync(),我还必须添加tester.idle().

testWidgets('stream builder', (tester) async {
  final textKey = Key('textKey');

  await tester.runAsync(() async { // IMPORTANT
    final stream = Observable.just('foo').delay(Duration(milliseconds: 1));

    var app = MaterialApp(
      home: StreamBuilder<String>(
        stream: stream,
        builder: (context, snapshot) => Text(
              snapshot.data ?? 'no data',
              key: textKey,
            ),
      ),
    );

    await tester.pumpWidget(app);
    await tester.idle(); // IMPORTANT
    await tester.pump(Duration.zero); // IMPORTANT
  });

  Text text = tester.widget(find.byKey(textKey));
  expect(text.data, equals('foo'));
});
Run Code Online (Sandbox Code Playgroud)

  • 测试器方法“idle()”和“pump(zero)”实际上在等式中添加了什么?他们帮助我解决了测试运行期间 BLoC 状态处理的类似问题,但我想了解原因:) (3认同)