I'm trying something like this:
const useSelector = jest.fn();
jest.mock('react-redux', () => ({
useSelector,
}));
Then trying to do something like this:
useSelector.mockReturnValueOnce({});
shallow(
<ComponentUsingUseSelector />
);
That will give me an error:
The module factory of
jest.mock()
is not allowed to reference any out-of-scope variables.
So if I can't use an out of scope variable for a mock then how would I return a different value for every test?
I'm trying something like this:
const useSelector = jest.fn();
jest.mock('react-redux', () => ({
useSelector,
}));
Then trying to do something like this:
useSelector.mockReturnValueOnce({});
shallow(
<ComponentUsingUseSelector />
);
That will give me an error:
The module factory of
jest.mock()
is not allowed to reference any out-of-scope variables.
So if I can't use an out of scope variable for a mock then how would I return a different value for every test?
Share Improve this question edited Apr 18, 2020 at 18:34 skyboyer 23.7k7 gold badges61 silver badges71 bronze badges asked Apr 18, 2020 at 14:43 HMRHMR 39.3k25 gold badges98 silver badges173 bronze badges3 Answers
Reset to default 6Simplified version, which also works:
import * as redux from 'react-redux'
jest
.spyOn(redux, 'useSelector')
.mockReturnValueOnce('first call')
Also, instead of relying on multiple calls to mockReturnValueOnce
it's better to just stub the necessary part of the store:
const locale = 'en'
const state = {
application: { locale },
}
jest
.spyOn(redux, 'useSelector')
.mockImplementation((callback) => callback(state))
The following seems to work, after reading tons of articles and documentation that does not do what I (think) need to do; finally found one that does.
import { useSelector } from 'react-redux';
jest.mock('react-redux', () => ({
useSelector: jest.fn(),
}));
describe('some test', () => {
it('do something', () => {
useSelector.mockImplementation(() => ('hello world'));
shallow(
<ComponentUsingUseSelector />
);
If it's called multiple times I can do:
describe('some test', () => {
it('do something', () => {
useSelector.
.mockReturnValueOnce('first call')
.mockReturnValueOnce('second call')
shallow(
<ComponentUsingUseSelector />
);
Update answer to versions react-redux
v8
Cannot redefine property: useSelector issue
If you're getting the following error:
TypeError: Cannot redefine property: useSelector
at Function.defineProperty (<anonymous>)
Apply this before tests:
import * as Redux from 'react-redux';
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn()
}));
Example:
import * as Redux from 'react-redux';
// This will enable to mock readonly
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn()
}));
describe('Component Tests', () => {
beforeEach(() => {
jest.spyOn(Redux, 'useSelector').mockReturnValue({
users: [] // your mock here
});
// or
// (useSelector as jest.Mock).mockImplementation(() => ({
// useSelector:[] your mock
// }));
});
test('should render component', () => {
render(<MyComponent />);
});
});