React function components may read from Redux state using react-redux
's useSelector
hook.
Consider this Redux state shape containing a title
of type string
:
const initialState = {
title: "",
};
Your state code might declare a selectTitle
selector to retrieve that title:
const selectTitle = (state) => state.title;
Your view code might use that selector to render the title:
const Heading = () => {
const title = useSelector(selectTitle);
return <h1>{title}</h1>;
};
You could set up Redux state with a full state tree:
const testState = {
title: "Test Title",
};
// Renders <h1>Test Title</h1>
<Provider store={configureStore()(testState)}>
<Heading />
</Provider>;
So much work! That testing setup's complexity and resultant pain can easily grow with your application. You're also relying a bunch of Redux state in order to test your React view. It can be useful to separate view and state logic in tests: especially when state is shared across many places.
Instead, mock-react-redux
can simplify or even replace any Redux interactions.
You have two options:
- Providing a mocked Redux state for your test
- Directly using predefined return values or mock functions for individual selectors
You can set mock Redux state for the duration of a test.
That state will be provided to selectors called by useSelector
.
mockReactRedux().state({
title: "Test Title",
});
// Renders <h1>Test Title</h1>
<Heading />;
.state
takes in a single parameter and can only be called once per test:
state
: A value to use as the root Redux state for the duration of the test
If your component only uses useSelector
and directly passes predefined selector functions to it,
you can completely remove its dependency on Redux state with .give
.
It takes two parameters:
selector
: Selector function to mock out return values forreturnValue
: Value to return whenever the selector is provided touseSelector
The returnValue
will be directly returned when useSelector
is called from that selector
:
mockReactRedux().give(selectTitle, "Test Title");
// Renders <h1>Test Title</h1>
<Heading />;
If you'd like more control over the return values, use .giveMock
to provide a Jest mock.
It takes two parameters:
selector
: Selector function to mock out return values formock
: Jest mock function to call in place of the selector
For example, you might want the selector to return a different value than the first on subsequent calls:
mockReactRedux().giveMock(
selectTitle,
jest
.fn()
.mockReturnValueOnce("First!")
.mockReturnValueOnce("Second.")
.mockReturnValue("Other times..."),
);
See Jest's mock functions for full documentation.
See FAQs for help choosing between these strategies and pracices for mocking selectors.