使用Jest模拟会导致"操作必须是普通对象.使用自定义中间件进行异步操作".

Kev*_*ica 9 javascript mocking jest redux redux-thunk

我有几个Redux-Thunk风格的函数,可以在一个文件中调度其他操作.其中一个动作将另一个作为其逻辑的一部分发送.它看起来类似于:

export const functionToMock = () => async (dispatch) => {
    await dispatch({ type: 'a basic action' });
};

export const functionToTest = () => async (dispatch) => {
    dispatch(functionToMock());
};
Run Code Online (Sandbox Code Playgroud)

在我实际遇到的情况下,函数更加复杂,并且每个函数都分派多个动作对象.结果,当我测试我的现实世界时functionToTest,我想模仿我的现实世界functionToMock.我们已经进行了functionToMock广泛的测试,我不想在这些测试中重复逻辑functionToTest.

但是,当我尝试这样的时候,就像这样:

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';

jest.mock('../exampleActions');
const actions = require('../exampleActions');

const mockStore = configureMockStore([thunk]);

describe('example scenario showing my problem', () => {
    test('functionToTest dispatches fuctionToMock', () => {
        actions.functionToMock.mockReturnValue(() => Promise.resolve());

        const store = mockStore({});

        store.dispatch(actions.functionToTest());

        expect(actions.functionToMock.mock.calls.length).toBe(1);
    });
});
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

 FAIL  test.js
  ? example scenario showing my problem › functionToTest dispatches fuctionToMock

    Actions must be plain objects. Use custom middleware for async actions.
        at Error (native)

      at dispatch (node_modules\redux-mock-store\dist\index-cjs.js:1:3137)
      at Object.dispatch (node_modules\redux-thunk\lib\index.js:14:16)
      at Object.<anonymous> (test.js:15:23)
Run Code Online (Sandbox Code Playgroud)

(我发布的示例代码实际上会产生此错误,如果您在具有Jest,Redux和Redux-Thunk的环境中设置它们.这是我的MVCE.)

我有一个想法是我可以将两个函数移动到不同的文件中.不幸的是,这样做会使我们项目的其余部分组织得非常显着,所以除非它是真正唯一的解决方案,否则我不愿意这样做.

如何functionToMockfunctionToTest没有出现此错误的情况下模拟我的测试?

Kev*_*ica 3

一种解决方案就是模拟functionToMock. 这个问题及其答案解释了如何做到这一点:How to mock Imported named function in Jest when module is unmocked

这个答案特别解释了,为了在使用 Babel 这样的转译器时使这种方法发挥作用,您可能需要引用exports.functionToMock而不是functionToMock内部functionToTest(在测试之外),如下所示:

export const functionToTest = () => async (dispatch) => {
    dispatch(exports.functionToMock());
};
Run Code Online (Sandbox Code Playgroud)