emitsDone
can be used if the Stream
is closed at some point.
E.g:
test('Test', () async {
final controller = StreamController<String>();
final stream = controller.stream;
final matcher = expectLater(
stream,
emitsInOrder(<dynamic>[
'Item1',
'Item2',
emitsDone,
]),
);
controller
..add('Item1')
..add('Item2')
..add('Item3')
..close();
await matcher;
await controller.close();
});
The test fails with error:
Expected: should do the following in order:
• emit an event that 'Item1'
• emit an event that 'Item2'
• be done
Actual: <Instance of '_ControllerStream<String>'>
Which: emitted • Item1
• Item2
• Item3
x Stream closed.
which didn't be done
As @Irn suggest, a more compact alternative for Stream
s that complete at some point is using toList
:
test('Test', () async {
final controller = StreamController<String>();
final stream = controller.stream;
final matcher = expectLater(stream.toList(), completion(<String>['Item1', 'Item2']));
controller
..add('Item1')
..add('Item2')
..add('Item3')
..close();
await matcher;
await controller.close();
});
If the Stream
is never closed, you can add a timeout and check the items that have been emitted in that period:
test('Test3', () async {
final controller = StreamController<String>();
final stream = controller.stream.timeout(const Duration(milliseconds: 200));
final matcher = expectLater(
stream,
emitsInOrder(<dynamic>[
'Item1',
'Item2',
]),
);
controller
..add('Item1')
..add('Item2');
await matcher;
await controller.close();
});