如何在Dart中对Stream.listen()进行单元测试

14

请考虑以下测试代码...

main() {
  StreamController controller;
  setUp(() {
    controller = StreamController.broadcast(sync: false);
  });

  tearDown(() {
    controller.close();
  });

  test('Stream listen test', () {
    var stream = controller.stream;

    stream.listen((event) {
      // >>>>> How can I test if this was called?? <<<<<<
    });

    controller.add('Here is an event!');
  });
}

...如何正确测试stream.listen(...)回调是否被调用?

stream.listen(...)没有返回Future,因此传统的expectAsyncX匹配器在这里不起作用。

也许有一些方法可以使用stream.listen(...)返回的StreamSubscription.asFuture()来实现?

1个回答

29
你可以使用 expectLater 函数等待来自你的Streamasync响应,并使用emits 比较你的Stream与你发出的值,就像这样:
  test('Stream listen test', () {
    var stream = controller.stream;

    final String value = 'Here is an event!';

    stream.listen((event) {
      // >>>>> How can I test if this was called?? <<<<<<
    });

    expectLater(stream, emits(value));

    controller.add(value);
  });

更新

您可以尝试在listen方法周围使用expectAsync1。如果未发出任何值,则会触发超时。

stream.listen(
      expectAsync1(
        (event) {
          expect(event, value);
        },
      ),
    );

这只会确认值已被发出...而不是stream.listen()内部的函数被调用。我正在寻找一种确认监听器被调用的方法。 - ra9r
3
它将确认函数已被调用。这正是“expectAsync1”所做的:它包装了一个函数,并要求调用该包装函数,否则测试将不成功。当调用包装函数时,它肯定会调用它所包装的函数。因此,如果测试成功,那么您可以确定传递给“expectAsync1”的函数参数也被调用了(恰好一次)。 - lrn
expectAsync1的扩展示例。 - Baker
1
你救了我的一天!感谢你的提示,我认为这并不容易找到!干杯! - Nicolas Dion-Bouchard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接