Reputation: 168
I'm trying to test a widget that contains a StreamBuilder and I'm unable to return data.
Widget:
class HomeView extends StatelessWidget {
final EventServiceRepository eventService;
HomeView({this.eventService});
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder<List<Event>>(
stream: this.eventService.getEvents(dates: dates),
builder: (context, snapshot) {
if (!snapshot.hasData) return HomeLoading();
return EventsView(events: snapshot.data);
},
)
);
}
}
Test:
class MockedEventService extends Mock implements EventServiceRepository {}
class MockedEventStream extends Mock implements Stream<List<Event>> {}
testWidgets('Should find EventsView', (WidgetTester tester) async {
final mockedEventService = MockedEventService();
final mockedEventStream = MockedEventStream();
when(mockedEventService.getEvents(dates: ['1/1/2021']))
.thenAnswer((_) => mockedEventStream);
when(mockedEventStream); // return list of events?
await tester.pumpWidget(HomeView(eventService: mockedEventService));
expect(find.byType(EventsView), findsOneWidget);
});
I've tried a few things with mockedEventStream
but It always returns snapshot.hasData == false
Upvotes: 2
Views: 1427
Reputation: 755
Two issues - first, you're mocking the Stream, but you're not putting any data on it, so the StreamBuilder assumes the Stream is empty. Second, once you do put data on the Stream, you need to pump the Widget a second time to refresh the StreamBuilder. I also personally wouldn't bother mocking the Stream itself.
My slightly revised version:
final mockedEventService = MockedEventService();
when(mockedEventService.getEvents()).thenAnswer((_) => Stream.value(true));
await tester.pumpWidget(MyHomePage(eventService: mockedEventService));
await tester.pump(Duration.zero);
expect(find.byKey(ObjectKey("B")), findsOneWidget);
Obviously need to change to reflect your original code (mock EventServiceRepository, return a Stream.value(List[]), check for the right Widget, etc etc).
Upvotes: 3