Reputation: 1621
my component has multiple selectors:
import { useSelector } from 'react-redux'
...
const data1 = useSelector(xxxxx)
const data2 = useSelector(yyyyy)
How properly mock each in test file?
import { useSelector } from 'react-redux'
jest.mock('react-redux', () => ({
useSelector: jest.fn()
}))
....
useSelector.mockImplementation(() => ({
dataready: true
}))
which selector it's really mocking in this case?
Upvotes: 5
Views: 11620
Reputation: 412
Don't mock the selector. You want to test the integration between Redux and React components, not the Redux implementation of selectors. If you use react-testing-library
it's pretty simple to hijack the render()
method and implement your store using a Redux Provider component. Here are the docs for setting up a reusable render function.
Here's your test re-written with the user in mind:
import { renderWithProviders } from '../../test-utils' // <-- Hijacked render
// Explanation of behavior
it('displays data when ready', {
renderWithProviders(<YourComponent />, {
preloadedState: {
someSlice: {
dataready: true // <-- Pass data for selector in store slice
}
}
})
// Check that something shows based on selector
expect(screen.getByTestId('some-testId')).toBeInTheDocument()
})
Upvotes: 4
Reputation: 1568
You'd want to do something like this, to get your spy, and then check on what it is called with and mockImplementation to prevent async if thats an issue for you, i'd suggest you provide state via the render function, rather than mock a selector implementation though.
import { useDispatch, useSelector } from 'react-redux';
const reactRedux = { useDispatch, useSelector };
const useDispatchMock = jest.spyOn(reactRedux, 'useDispatch');
Upvotes: 0
Reputation: 21
import * as redux from 'react-redux';
...
beforeEach(() => {
jest
.spyOn(redux, 'useSelector')
.mockReturnValueOnce(xxxx)
.mockReturnValueOnce(yyyy);
});
Upvotes: 2