I'm new to testing and I wanted to follow the DRY principle for my unit test cases. In my test cases, I'm mocking react-redux's useSelector and useDispatch and currently writing the same mock in all the tests wherever react-redux is used. Below is one of my test case.
import React from 'react';
import { shallow } from 'enzyme';
import LayoutComponent from './LayoutComponent';
const mockDispatch = jest.fn();
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
useDispatch: () => mockDispatch
}));
const setup = () => {
return shallow(<LayoutComponent />)
}
const mockState = (state) => {
return useSelector.mockImplementationOnce(callback => {
return callback(state);
})
}
jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useLocation: () => ({
pathname: "localhost:3000/"
})
}));
describe('LayoutComponent', () => {
afterEach(() => {
jest.clearAllMocks();
})
test('Calls getUserInfo on mount', () => {
setup();
expect(mockDispatch).toHaveBeenCalledWith(expect.any(Function));
expect(mockDispatch).toHaveBeenCalledTimes(1);
});
});
Instead of writing this mock in all the test files, I want to keep react-redux mock separate so that I can import it in all the files wherever these are used and no need to write them again and again.
Can anyone please help me with this. Thank you in advance.
UPDATE
I have created a directory called __mocks__
right beside node_modules
folder and inside __mocks__
folder I've created react-redux.js
file. Inside the file I've the below mock functions.
const mockDispatch = jest.fn()
module.exports = {
...jest.requireActual('react-redux'),
__esModule: true,
useSelector: jest.fn(),
useDispatch: () => mockDispatch,
mockDispath,
};
Below is the test
import React from 'react';
import { shallow } from 'enzyme';
import ResolutionCount from '../ResolutionCount';
import { mockDispatch, mockState } from 'react-redux';
const setup = props => {
return shallow(<ResolutionCount componentUsedIn={props} />)
}
describe("ResolutionCount component", () => {
test("testing component with prop value", () => {
mockState({
userInfoReducer: {
userInfo: [
{
user_id: 'some id',
user_name: 'some name',
user_email: 'someemail@email.com',
user_pic: null,
is_admin: true,
is_super_user: false,
},
]
}
});
setup("my resolutions");
expect(mockDispatch).toHaveBeenCalledWith({
type: "SET_RESOLUTION_STATUS_COUNT_BAR_CHART_FETCHING_DATA",
payload: true,
});
})
})
so now when I'm running the test I'm getting the error saying that
TypeError: (0 , _reactRedux.mockState) is not a function
describe("ResolutionCount component", () => {
11 | test("testing component with prop value", () => {
> 12 | mockState({
| ^
13 | userInfoReducer: {
14 | userInfo: [
15 | {
Reusable mocks from __mocks__
directory is a way that Jest provides for this.
In case a spy needs to be accessed directly in order to modify the implementation or assert it, it can be added to module exports, name collisions with existing exports have to be avoided with mock
prefix or else.
<root>/__mocks__/react-redux.js
const mockDispatch = jest.fn();
module.exports = {
...jest.requireActual('react-redux'),
__esModule: true,
useSelector: jest.fn(),
useDispatch: jest.fn(() => mockDispatch),
mockDispatch
};
The mock is supposed to be automatically applied on import. Then mockDispatch
can be imported in tests as usual:
import { mockDispatch } from 'react-redux';