tezvyn:

How do you widget-test states without real network calls?

AI-drafted, machine-checkedSource: docs.flutter.devintermediate

This tests UI isolation from I/O. Mock the repository with Mockito, stub methods to yield loading, success, and error, and inject it via constructor or provider. Avoid real HTTP calls or unmocked clients in widget tests.

WHAT THIS TESTS: The interviewer wants to know if you understand test isolation and dependency injection in UI tests. Widget tests should run fast and deterministically, so they cannot depend on real network latency or external services. The question reveals whether you think about boundaries between the UI layer and the data layer, and whether you know how to replace a real repository with a fake implementation that you control.

A GOOD ANSWER COVERS: First, explain that the repository must be injected into the widget rather than constructed inside it, so you can swap it for a mock. Second, describe using a mocking library like Mockito to generate a mock repository that implements the same interface or extends the same base class as the real one. Third, note that you stub the repository methods to return specific values or streams for each state, such as a loading emission followed by a success payload or an error exception. Fourth, explain how to provide the mock to the widget, either by passing it directly through the widget constructor or by overriding the dependency in a provider that sits above the widget in the tree. Fifth, mention that you use widgetTester.pumpWidget to build the tree and then pump or pumpAndSettle to advance time, asserting with finders that the correct text, loaders, or error icons are rendered.

COMMON WRONG ANSWERS: A major red flag is suggesting that you call the real API and just assert on the result, which makes the test flaky and slow. Another mistake is hard-coding the repository instantiation inside the widget using a global singleton or a direct constructor call, because that prevents substitution during tests. Some candidates also forget to stub async behavior and then wonder why the widget never leaves the loading state, or they stub a future but fail to pump the tester to let microtasks complete.

LIKELY FOLLOW-UPS: The interviewer might ask how you would handle streams versus futures, or how you would test retry logic without waiting for real timers. They may also ask what you would do if the widget uses a global service locator like GetIt, or how you would structure the test if the repository were a sealed class or interface in Dart. Another follow-up is how to verify that the widget calls a specific repository method with the correct arguments.

ONE CONCRETE EXAMPLE: Suppose you have a UserProfile widget that takes a UserRepository in its constructor. In your test, you create a mock repository with Mockito and stub fetchUser to return a Future.value for success, throw an exception for error, or emit a stream of ConnectionState values for loading. You then build the widget with tester.pumpWidget(MaterialApp(home: UserProfile(repository: mockRepository))). For the loading case, you immediately expect a CircularProgressIndicator. For success, you await tester.pumpAndSettle and expect the user's name. For error, you catch the thrown exception in the stub and expect an error message widget.

Read the original → docs.flutter.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.