Stream Unit Test in Flutter with Mokito
I’m creating a new app with Flutter and I tested units with Mokito.
I can test Future functions with await
.
How can I test stream?
Mocking stream
First of all I should mock stream. I asked to GPT and he answered following.
// Set up the behavior of the mock controller
when(mockController.stream).thenAnswer((_) => Stream.fromIterable([1, 2, 3]));
// Expectations: we expect the stream to produce three numbers
expectLater(producer.numberStream, emitsInOrder([1, 2, 3]));
It seemed like to mock by returning the stream created by fromIterable
. Therefore I attempted the mocking like this.
final Iterable<Message> messages = [message];
when(chatMessageDatabaseService.streamMessages(chatId))
.thenAnswer((value) => Stream.fromIterable(messages));
However compile had been failed with this error.
It’s mean I should give [[Message]] instead of [Message].
So I defined one more variable messageEvents
.
final Iterable<Iterable<Message>> mesaageEvents = [messages];
when(chatMessageDatabaseService.streamMessages(chatId))
.thenAnswer((value) => Stream.fromIterable(mesaageEvents));
expectLater
When I tested Future functions, expect
is enough with await
. How can we expect streamed data? There is expectLater
instead of expect
.
Usage is very simple. Give stream and matcher like below.
expectLater(messageStream, emitsInOrder(mesaageEvents));
emitsInOrder means we expect messageStream will emit event by ordering with same sequence of messageEvents
.
Full Source
test('streamMessages method should return Message Stream', () async {
final Iterable<Message> messages = [message];
when(chatMessageDatabaseService.streamMessages(chatId))
.thenAnswer((value) => Stream.value(messages));
final messageStream = service.streamMessages(chatId);
expectLater(messageStream, emitsThrough(messages));
});