unit-testingdartflutter-test

How to unit test Stream.listen() in Dart


Consider the following test code ...

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

... what is the correct way to test that the stream.listen(...) call-back was invoked?

stream.listen(...) doesn't return a Future so traditional expectAsyncX style matchers will not work here.

Perhaps there is some way to use the StreamSubscription.asFuture() that is returned by stream.listen(...)?


Solution

  • You can use expectLater function to wait for async response from your Stream and compare your Stream to your emitted value using emits , like this:

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

    UPDATE

    You can try expectAsync1 around your listen method. If no value is emitted, the timeout will be fired.

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