在测试用例中编写笑话模拟时遵循 DRY 原则 - React 和 Jest

Follow DRY principles while writing jest mocks in test cases - React and Jest

我是测试新手,我想对我的单元测试用例遵循 DRY 原则。在我的测试用例中,我正在模拟 react-redux 的 useSelector 和 useDispatch,并且目前在所有使用 react-redux 的测试中编写相同的模拟。下面是我的测试用例之一。

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);
    });

});

我不想在所有测试文件中编写这个 mock,而是希望将 react-redux mock 分开,这样我就可以将它导入到所有使用这些文件的文件中,而无需一次又一次地编写它们。

谁能帮我解决这个问题。提前谢谢你。

更新

我在 node_modules 文件夹旁边和 __mocks__ 文件夹内创建了一个名为 __mocks__ 的目录,我创建了 react-redux.js 文件。在文件中,我有以下模拟函数。

const mockDispatch = jest.fn()

module.exports = {
    ...jest.requireActual('react-redux'),
    __esModule: true,
    useSelector: jest.fn(),
    useDispatch: () => mockDispatch,
    mockDispath,
};

下面是测试

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,
        });

    })
})

所以现在当我 运行 测试时,我收到错误提示

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 |                     {

来自 __mocks__ 目录的可重用模拟是 Jest 为此提供的一种方式。

如果需要直接访问间谍以修改实现或断言它,可以将其添加到模块导出中,必须使用 mock 前缀避免与现有导出的名称冲突,否则.

/__mocks__/react-redux.js

const mockDispatch = jest.fn();

module.exports = {
    ...jest.requireActual('react-redux'),
    __esModule: true,
    useSelector: jest.fn(),
    useDispatch: jest.fn(() => mockDispatch),
    mockDispatch
};

模拟应该在导入时自动应用。然后 mockDispatch 可以像往常一样在测试中导入:

import { mockDispatch } from 'react-redux';