【问题标题】:Follow DRY principles while writing jest mocks in test cases - React and Jest在测试用例中编写 jest mocks 时遵循 DRY 原则 - React 和 Jest
【发布时间】:2020-09-21 09:36:24
【问题描述】:

我是测试新手,我想在我的单元测试用例中遵循 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);
    });

});

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

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

更新

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

【问题讨论】:

    标签: reactjs unit-testing jestjs enzyme dry


    【解决方案1】:

    __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';
    

    【讨论】:

    • 感谢您的回复。 Jest对我来说很陌生!在我的反应项目中,我需要在哪里创建 mock 文件夹?我已经在 src/ 目录中创建了它。您能否告诉我如何在测试用例中访问它。因为我还有一个测试函数mockState,它将模拟useSelector。请帮忙
    • 它需要和node_modules在同一个地方,见jestjs.io/docs/en/manual-mocks#mocking-node-modules。您需要像任何其他导出一样访问它,import { mockDispatch } from 'react-redux'
    • 所以在这种情况下,每当我删除 node_modules 文件夹时,我都需要重新创建文件吗?另外,我们不会将 node_modules 目录推送到 github,否则它会被遗漏,对吧?
    • 这是特定于您的设置的。看来您使用 create-react-app 项目,__mocks__ 可能应该位于 src 而不是根目录中。见github.com/facebook/create-react-app/issues/7539
    • 代码中有错字。应该是mockDispatch,而不是mockDispath
    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2018-09-17
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多