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

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

export const functionToTest = () => async (dispatch) => {
    dispatch(functionToMock());
};

在我实际遇到的情况下,这些函数既涉及更多功能,又各自分配多个 Action 对象。结果,当我测试真实世界的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);
    });
});

我收到此错误:
 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)

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

我曾经想到的是我可以将这两个函数移到不同的文件中。不幸的是,这样做会严重破坏项目其余部分的组织方式,因此,除非它确实是唯一的解决方案,否则我不愿意这样做。

如何在测试中为functionToMock模拟functionToTest而不会出现此错误?

最佳答案

一种解决方案是仅模拟functionToMock。该问题及其答案说明了如何执行此操作:How to mock imported named function in Jest when module is unmocked

This answer in particular解释说,为了在使用像Babel这样的编译器时使这种方法起作用,您可能需要在exports.functionToMock(测试之外)中引用functionToMock而不是functionToTest,例如:

export const functionToTest = () => async (dispatch) => {
    dispatch(exports.functionToMock());
};

10-06 04:05