Search code examples
flutterdartblocflutter-bloc

Get Flutter BLoC Current State - Flutter unit test


Is possible to get current state in the unit test code base

Test Code

group('registerWithFacebookEvent', () {
    const response =
        RegisterUser(name: "Dolapo Olakanmi", message: "Successful");
    test(
        'should validate emit sequence when registerWithFacebook usecase is successful',
        () async {
      when(registerUserWithFacebook(const NoParam()))
          .thenAnswer((_) async => const Right(response));

      const expected = [Success(response: response)];
      expectLater(bloc.stream, emitsInOrder(expected));
      bloc.add(RegisterUserWithFacebookEvent());
      expect(bloc.state, expected.first);
    });
  });

Prod Code

if (event is RegisterUserWithFacebookEvent) {
   final failureOrSuccess = await registerUserWithFacebook(const NoParam());
   emit(failureOrSuccess.fold(
     (l) => throw UnimplementedError(), (r) => Success(response: r)));
}

The test fails because the line expect(bloc.state, expected.first) fails and the reason is the bloc.state return the initial state which is in my case:

Expected: Success:<Success()>
  Actual: RegisterUserInitial:<RegisterUserInitial()>

Solution

  • On a quick first look it looks like you are missing an await before your expectLater inside of theasync test callback function.

    Also put the expectLater below your bloc.add and also include the previous states (like init, registration, loading, etc) in the expected state list, because it is the list of all states that are emitted from the bloc.

    So any emitted states from the bloc should be included inside of the expected list (just not the initialState param of the bloc constructor).

    So similar to the following:

    group('registerWithFacebookEvent', () {
        const response =
            RegisterUser(name: "Dolapo Olakanmi", message: "Successful");
        test(
            'should validate emit sequence when registerWithFacebook usecase is successful',
            () async {
          when(registerUserWithFacebook(const NoParam()))
              .thenAnswer((_) async => const Right(response));
    
          const expected = [..., RegisterUserInitial(), ..., Success(response: response)];
          final Future<void> matcher = expectLater(bloc.stream, emitsInOrder(expected));
          bloc.add(RegisterUserWithFacebookEvent());
          await matcher;
          expect(bloc.state, expected.last);
        });
      });