Bloc: [Question] Testing navigation in BlocListener with mocked Bloc

Created on 13 Mar 2020  路  2Comments  路  Source: felangel/bloc

Hi Felix, I just wanted to say thanks for all the work you've done!

I've been using your Flutter_Bloc package for a bit but I just recently started trying to test some of my code using Mockito and Bloc_Test. Right now, my code using the bloc with a listener to push a widget is fairly simple and is actually working fine in the emulator, but testing it the way I'm thinking has not been working out for me. In particular, I've been struggling with a UI test for signing a user in through an authentication bloc. To keep these tests lightweight, I wanted to mock out the bloc and just stub in each state individually to see how the UI handles them on their own.

So far, I've been able to test the BlocBuilder just fine using when(authenticationBlocMock.state).thenAnswer((_) => AuthenticationInProgress()) - the UI picks up the state and builds the loading indicator widget that I'm expecting.

My problem has been with the BlocListener that listens for state and if authentication is successful, pushes a new widget to the UI (I plan to add snackbars for failure states once I get this working). I've tried using the same approach as I did with the BlocBuilder above, as well as using the whenListen() method from Bloc_Test. With whenListen(), I've tried returning a single state and list of states - neither has seemed to work. For some reason, I can't seem to hook into the listener - I've tried putting a breakpoint at the listener's if check but it never ends up stopping there.

From the BlocListener documentation, it looks like

/// The [listener] is guaranteed to only be called once for each [state] change
/// unlike the [builder] in [BlocBuilder].

By debugging, I can see that the stub of authenticationBlocMock.state sets the _previousState field of the listener, but for some reason, the methods I tried above aren't triggering a state change that the listener picks up. I've tried various combinations of tester.pump() to try to trigger a rebuild that might pick up the new states with no luck either. I've looked through other examples and issues but they all seem to focus on using a real instance of the bloc or on the BlocBuilder interaction with a mocked bloc.

I created a trimmed down sample project that has the SignInScreenTest I've been struggling with, along with the SignInScreen UI and AuthenticationBloc for context. The failing test is 'Test listen for AuthenticationSuccess state should show Dashboard'.

Any advice you have on testing a BlocListener like this would be greatly appreciated - whether there is some better strategy for these tests, something I'm not understanding about the framework, or anything else in general!

Thanks!

question

Most helpful comment

Well I feel pretty stupid now馃槗. Thought I had tried that but I guess not! Thanks for taking the time to help though, I really appreciate it!

All 2 comments

Hi @kgain21 馃憢
Thanks for opening an issue!

I've created a pull request with the required updates to fix the test. Hope that helps and let me know if you have any questions 馃憤

Well I feel pretty stupid now馃槗. Thought I had tried that but I guess not! Thanks for taking the time to help though, I really appreciate it!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clicksocial picture clicksocial  路  3Comments

MahdiPishguy picture MahdiPishguy  路  3Comments

abinvp picture abinvp  路  3Comments

RobPFarley picture RobPFarley  路  3Comments

hivesey picture hivesey  路  3Comments