Flutter: how to mock a stream

2,677

You can create a mock Stream by creating a mock class using mockito. Here's a sample on how one can be implemented.

import 'package:mockito/mockito.dart';

class MockStream extends Mock implements Stream<int> {}

void main() async {
  var stream = MockStream();
  when(stream.first).thenAnswer((_) => Future.value(7));
  print(await stream.first);

  when(stream.listen(any)).thenAnswer((Invocation invocation) {
    var callback = invocation.positionalArguments.single;
    callback(1);
    callback(2);
    callback(3);
  });

  stream.listen((e) async => print(await e));
}
Share:
2,677
Little Monkey
Author by

Little Monkey

I'm just a little monkey!

Updated on December 07, 2022

Comments

  • Little Monkey
    Little Monkey over 1 year

    I´m using the bloc pattern and now I came to test the UI. My question is: how to mock streams? This is the code that I have: I give to the RootPage class an optional mockBloc value and I will set it to the actual _bloc if this mockBloc is not null

    class RootPage extends StatefulWidget {
    
      final loggedOut;
      final mockBlock;
      RootPage(this.loggedOut, {this.mockBlock});
    
      @override
      _RootPageState createState() => _RootPageState();
    }
    
    
    class _RootPageState extends State<RootPage> {
    
      LoginBloc _bloc;
    
         @override
          void initState() {
            super.initState();
            if (widget.mockBlock != null)
              _bloc = widget.mockBlock;
            else
              _bloc = new LoginBloc();
            if (widget.loggedOut == false)
            _bloc.startLoad.add(null);
          }
    
        ...
    
     @override
      Widget build(BuildContext context) {
        return StreamBuilder(
            stream: _bloc.load,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Column(
                    children: <Widget>
                         ...
    

    This is what I´ve tried:

      testWidgets('MyWidget', (WidgetTester tester) async {
        MockBloc mockBloc = new MockBloc();
        MockTokenApi mockTokenApi = new MockTokenApi();
    
        await tester.pumpWidget(new MaterialApp(
            home: RootPage(false, mockBlock: mockBloc)));
    
        when(mockBloc.startLoad.add(null)).thenReturn(mockBloc.insertLoadStatus.add(SettingsStatus.set));   //this will give in output the stream that the StreamBuilder is listening to (_bloc.load)
        });
       await tester.pump();
        expect(find.text("Root"), findsOneWidget);
    
      });
    

    The result that I achieve is always to get:

    The method 'add' was called on null

    when _bloc.startLoad.add(null) is called

    • Maks
      Maks about 5 years
      In the mocks when(), you are calling add() on mockBloc.insertLoadStatus but I don't see where or how you defined insertLoadStatus?