使用开玩笑模拟会导致"Actions must be plain objects. Use custom middleware for async actions."



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

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

在我实际遇到的情况下,这些函数都涉及更多,并且每个函数都调度多个操作对象。因此,当我测试我的现实世界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_modulesredux-mock-storedistindex-cjs.js:1:3137)
at Object.dispatch (node_modulesredux-thunklibindex.js:14:16)
at Object.<anonymous> (test.js:15:23)

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

我的一个想法是我可以将这两个函数移动到不同的文件中。不幸的是,这样做会极大地破坏我们项目的其余部分的组织方式,所以我不愿意这样做,除非它真的是唯一的解决方案。

如何在测试中模拟functionToMockfunctionToTest而不会收到此错误?

一种解决方案就是模拟functionToMock。这个问题及其答案解释了如何做到这一点:当模块未被嘲笑时,如何在 Jest 中模拟导入的命名函数

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

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

您在问题中的示例帮助我修复了一个单独的错误。解决方案是将thunk扔进const mockStore = configureMockStore([thunk]);.谢谢!

相关内容

最新更新