Search code examples
flutterunit-testingbloc

How to unit test bloc with network relative repostitory?


I create a bloc call Authentication. This bloc emit two state call Autenticated and UnAuthenticated base on AuthenticationRepository which dependency injected into bloc.

Then I tring to create a mocked MockAuthenticationRepository for unit test but I got two different state so I have to create two different version of repository like MockAutenticatedAuthenticationRepository and MockUnAuthenticatedAuthenticationRepository to test these two case.

But maybe there is a another bloc emit 5 or 6 state base on repository then i have to create 5 to 6 mocked repository for it. This sound not terribly wrong because one bloc shondn't growing unlimit. But I still looking for better way to solve this. Anyone got better idea?


Solution

  • you can use the package mocktail (https://pub.dev/packages/mocktail) to set up the correct behavior of the repository. It´s also a good idea to use the package bloc_test (https://pub.dev/packages/bloc_test) to implement bloc unit tests.

    import 'package:mocktail/mocktail.dart';
    
    class MockAutenticatedAuthenticationRepository extends Mock implements AutenticatedAuthenticationRepository {};
    
    void main() {
      late MockAutenticatedAuthenticationRepository authMock;
      late AuthBloc bloc;
    
      setUp(() {
        authMock = MockAutenticatedAuthenticationRepository();
        bloc = AuthBloc(auchRepository: authMock);
      });
    
    
     blocTest(
          'should emit [AuthLoadingState, AuthSuccessState] when login data is correct',
          build: () {
            when(() => authMock.doAuth(any())).thenAnswer((_) async => true);
            return bloc;
          },
          act: (dynamic b) => b.add(AuthEvent.login("username","password")),
          expect: () => [AuthState.loading(), AuthState.success()],
        );
    
       blocTest(
          'should emit [AuthLoadingState, AuthFailureState] when login data is incorrect',
          build: () {
            when(() => authMock.doAuth(any())).thenAnswer((_) async => false);
            return bloc;
          },
          act: (dynamic b) => b.add(AuthEvent.login("username","wrong password")),
          expect: () => [AuthState.loading(), AuthState.failure()],
        );
    }
    

    You have to adapt the method calls and so on, because i don´t have your example code. But i think that should help you solving your problem.