Skip to content
tezvyn:

Unit test a BLoC handling an AddItem event and emitting state

Source: pub.devMediumHow cards are made

Summary

Whether you know BLoC testing idioms and why bloc_test beats manual assertions.

Key points

Use blocTest with build, act, expect; mention seed, skip, and mocktail for dependencies.

What's really being asked

This question checks whether you understand how to verify BLoC behavior through its public API of events and states rather than its internal implementation. The interviewer wants to see that you know how to set up a controlled environment, trigger state changes via events, and assert on ordered emissions without fragile stream boilerplate. It also surfaces whether you know the ecosystem tooling that makes this repeatable.

The full answer

First, import bloc_test and instantiate the BLoC inside the build callback so each test gets a fresh instance. Second, use the act callback to add the AddItem event to the bloc under test. Third, use the expect callback to return a list of state matchers that must be emitted in exact order after act runs. Fourth, mention that bloc_test automatically closes the stream and verifies no extra states were emitted, which removes the need for manual subscriptions and completers. Fifth, note that mocktail works with bloc_test to stub repositories or data sources injected into the BLoC, keeping the test isolated to state-machine logic.

The mistakes people make

A red flag is manually creating a StreamController, listening to bloc.stream, and collecting states in a list for manual comparison; this is error-prone and omits the automatic close check. Another mistake is calling emit or onChange directly from the test instead of driving the bloc through add, because that bypasses the event handler and event transformer logic. A third wrong pattern is forgetting to seed the initial state and then asserting on it, which causes off-by-one failures when the first emission is actually the unchanged seed state.

What usually comes next

The interviewer may ask how you test async side effects like debounce or throttle, where you would use the wait parameter in blocTest with a Duration. They might also ask how to verify that a repository method was called exactly once, which is done in the verify callback of blocTest. Another follow-up is testing error paths by using the errors parameter to assert that a specific exception is thrown, or asking how you would test a Cubit instead of a BLoC, which uses the same blocTest helper but typically omits the event layer.

A concrete example

Suppose a ShoppingBloc starts with an empty list state. Using blocTest, you set build to return ShoppingBloc with a mocked repository, act to add AddItem('Milk'), and expect to return a matcher list containing a state whose items list equals ['Milk']. If the BLoC debounces rapid AddItem events, you would add wait: const Duration(milliseconds: 300) so blocTest pauses before evaluating expect. You could also use seed: () => ShoppingState(items: ['Bread']) to start mid-session and assert the new state appends 'Milk' to the existing list.

Interview question

What is a key advantage of using blocTest over manually listening to bloc.stream when verifying state emissions after an AddItem event?

  • a.blocTest manages the subscription, asserts exact ordered emissions, and automatically verifies no extra states were emittedCorrect
  • b.blocTest removes the need for a build callback by caching the BLoC instance between test runs
  • c.blocTest bypasses the event handler and lets you invoke emit directly for simpler state setup
  • d.blocTest only checks the final state, ignoring intermediate emissions caused by event transformers
Why?

blocTest eliminates fragile manual stream boilerplate by handling subscriptions, enforcing ordered state matchers, and failing if unexpected states leak. Option C is tempting but wrong because calling emit directly bypasses the event handler and transformer logic, undermining the test.

Just read this? Test yourself on what you have been reading.

Read the original → pub.dev

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on flutter — each one lists the topics its interview covers.

See open roles