Dart - unit test of a stream event timing out

1.8k Views Asked by At

This is a very simplified version of the problem I have encountered when trying to unit tests streams.

The test checks that the correct event has been added to the stream - it appears to work fine - for example, change the value add( 'test') to add( 'test2') will fail the test.

But when you comment out the line fireKeepAliveMessage(message); so that the event does not throw, the unit test will simply run forever.

How can I add some sort of timeout to the test? Or is there a better approach to this problem?

library stream_test;

import "package:unittest/unittest.dart";
import "dart:async";

void main() {
   test("aa", () {
   StreamController streamController = new StreamController();

   streamController.add( "test");
   Stream underTest = streamController.stream;

   underTest.first.then(expectAsync((e){
        expect( e, equals( "test"));
   })); 
 });
}
2

There are 2 best solutions below

1
On

I would do it like:

library stream_test;

import "package:unittest/unittest.dart";
import "dart:async";

void main() {
  test("aa", () {
    StreamController streamController = new StreamController();

    Timer t;

    Stream underTest = streamController.stream;
    underTest.first.then(expectAsync((e) {
      expect(e, equals("test"));
      if (t != null) {
        t.cancel();
      }
    }));

    t = new Timer(new Duration(seconds: 3), () {
      fail('event not fired in time');
    });

    streamController.add("test");
  });
}
0
On

Stream class has method for this.

 Stream timeout(Duration timeLimit, {Function void onTimeout(EventSinksink)})

Creates a new stream with the same events as this stream.

Whenever more than timeLimit passes between two events from this stream, the onTimeout function is called.

The countdown doesn't start until the returned stream is listened to. The countdown is reset every time an event is forwarded from this stream, or when the stream is paused and resumed.

The onTimeout function is called with one argument: an dart-async.EventSink that allows putting events into the returned stream. This EventSink is only valid during the call to onTimeout.

If onTimeout is omitted, a timeout will just put a dart-async.TimeoutException into the error channel of the returned stream.

The returned stream is not a broadcast stream, even if this stream is.