Jest · Unit tests that survive refactors
How do you test Redux-connected components?
Short answer
Render the component inside a real store provider with a fresh store per test, and mock the API rather than the selectors. Assert on what the user sees after actions dispatch.
A connected component is an integration point between UI, selectors and reducers. If you mock useSelector, you prove almost nothing about that integration. A real store with real reducers and a mocked network boundary tests the wiring that actually breaks in production.
function renderWithStore(ui: React.ReactElement, preloaded?: Partial<State>) {
const store = configureStore({
reducer: rootReducer,
preloadedState: preloaded,
});
return {
store,
...render(<Provider store={store}>{ui}</Provider>),
};
}
test("shows items loaded from the API", async () => {
renderWithStore(<ItemList />);
expect(await screen.findByText("Keyboard")).toBeInTheDocument();
});What to test where
- Reducers and selectors as pure functions, with table-driven cases
- Connected components through a real store and mocked API
- Thunks and listeners with a mocked store or a test server
- Avoid mocking selectors, because that bypasses the state mapping
Create a new store per test so actions from one case cannot leak into another. If the store is expensive, a factory that reuses the reducer map is still cheap. Use preloadedState to put the component in a specific scenario without dispatching a long setup sequence.
configureStore is the standard test setup. It includes the thunk middleware and development checks by default, so tests exercise the same middleware stack as the app.Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why is mocking useSelector a weak test strategy?
- 2How do you put the store in a specific state for one test?
- 3How do you test a thunk?
- 4Why create a fresh store per test?
Say it in the interview
I render connected components inside a real store with the real reducers and a mocked API. That tests the selector-to-UI wiring, which is where integration bugs live. I use preloadedState to set up a scenario and a fresh store per test to avoid leaks. Reducers and selectors I test separately as pure functions, and I avoid mocking useSelector.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.