【问题标题】:How do you test StreamBuilder in Flutter using Mockito?如何使用 Mockito 在 Flutter 中测试 StreamBuilder?
【发布时间】:2026-01-19 15:55:01
【问题描述】:

我正在尝试测试一个包含 StreamBuilder 的小部件,但我无法返回数据。

小部件:

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

测试:

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

我用mockedEventStream 尝试了一些东西,但它总是返回snapshot.hasData == false

【问题讨论】:

    标签: flutter mockito stream-builder


    【解决方案1】:

    两个问题 - 首先,您正在模拟 Stream,但您没有在其上放置任何数据,因此 StreamBuilder 假定 Stream 为空。其次,一旦您将数据放到 Stream 上,您需要再次对 Widget 进行泵送以刷新 StreamBuilder。我个人也不会费心嘲笑 Stream 本身。

    我稍微修改过的版本:

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

    显然需要更改以反映您的原始代码(模拟 EventServiceRepository、返回 Stream.value(List[])、检查正确的 Widget 等)。

    【讨论】: