Bloc: How to test bloc state Stream in v2.0.x

Created on 2 Dec 2019  路  3Comments  路  Source: felangel/bloc

I'm struggling to adapt my tests after the migration to the latest version of bloc.

The code i'm trying to test is the following:

  ProfileBloc({
    @required this.userBloc,
    @required this.userRepository,
    @required this.profileEmail,
  }) {
    this.userBloc.listen((userState) {
      if(userState is UserSuccess) {
        if(userState.currentUser.email == profileEmail) {
          add(ProfileUpdated(user: userState.currentUser, isCurrentUser: true));
        } else {
          userSub?.cancel();
          userSub = this
              .userRepository
              .getUserByEmail(this.profileEmail)
              .listen((user) {
                add(ProfileUpdated(user: user, isCurrentUser: false));
              });

          userSub.onError((error) => debugPrint(
            "Error loading profile with mail [$profileEmail]: $error",
          ));
        }
      }
    });
  }

In the constructor of ProfileBloc i'm listening the state changes of UserBloc in order to emit ProfileUpdated with different information by the fact that the user is the logged one or not.

Since in the last version now the bloc is already a Stream itself, how can i mock this behaviour?

My attempt of setUp so far have been something like that:

      setUp(() {
        mockUserRepository = MockUserRepository();
        mockUserBloc = MockUserBloc();
        when(mockUserBloc).thenAnswer((_) {
          return Stream<UserState>.value(UserSuccess(currentUser: fakeCurrentUser));
        });
        profileBloc = ProfileBloc(
          userBloc: mockUserBloc,
          userRepository: mockUserRepository,
          profileEmail: testEmail,
        );
      });

But since is not a real method I can't mock it like this.

Any help?

*Note: i'm aware of bloc_test but I can't use it at the moment because of some compatibility issues with another dependency.

bloc_test question

Most helpful comment

Without bloc_test you would need to stub listen manually like:

when(bloc.listen(any,
        onError: anyNamed('onError'),
        onDone: anyNamed('onDone'),
        cancelOnError: anyNamed('cancelOnError')))
    .thenAnswer((Invocation invocation) {
  return stream.listen(
    invocation.positionalArguments.first,
    onError: invocation.namedArguments['onError'],
    onDone: invocation.namedArguments['onDone'],
    cancelOnError: invocation.namedArguments['cancelOnError'],
  );
});

I would highly recommend using whenListen from bloc_test instead.

Closing for now but feel free to comment with additional questions and I'm happy to continue the conversation 馃憤

All 3 comments

Hi @nerder 馃憢
Thanks for opening an issue.

You can use whenListen from the bloc_test package to mock the stream of states from your mockUserBloc.

whenListen(mockUserBloc, Stream.fromIterable([UserSuccess(currentUser: fakeCurrentUser)]));

Hope that helps 馃憤

This for sure helps, but what will be the way of doing this without bloc_test?

Without bloc_test you would need to stub listen manually like:

when(bloc.listen(any,
        onError: anyNamed('onError'),
        onDone: anyNamed('onDone'),
        cancelOnError: anyNamed('cancelOnError')))
    .thenAnswer((Invocation invocation) {
  return stream.listen(
    invocation.positionalArguments.first,
    onError: invocation.namedArguments['onError'],
    onDone: invocation.namedArguments['onDone'],
    cancelOnError: invocation.namedArguments['cancelOnError'],
  );
});

I would highly recommend using whenListen from bloc_test instead.

Closing for now but feel free to comment with additional questions and I'm happy to continue the conversation 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tigranhov picture tigranhov  路  3Comments

abinvp picture abinvp  路  3Comments

clicksocial picture clicksocial  路  3Comments

shawnchan2014 picture shawnchan2014  路  3Comments

ricktotec picture ricktotec  路  3Comments