使用 Jest 模拟结果 "Actions must be plain objects. Use custom middleware for async actions."
Using Jest mocks results in "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_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。)
我的一个想法是我可以将这两个函数移动到不同的文件中。不幸的是,这样做会极大地破坏我们项目其余部分的组织方式,所以我不愿意这样做,除非它确实是唯一的解决方案。
如何在 functionToTest
的测试中模拟 functionToMock
而不会出现此错误?
一个解决方案就是模拟 functionToMock
。这个问题及其答案解释了如何这样做:How to mock imported named function in Jest when module is unmocked
This answer in particular 解释说,为了让这种方法在您使用像 Babel 这样的转译器时起作用,您可能需要在 functionToTest
(在你的测试之外),像这样:
export const functionToTest = () => async (dispatch) => {
dispatch(exports.functionToMock());
};
你在问题中的例子帮助我修复了一个单独的错误。解决方案是将 thunk
扔进 const mockStore = configureMockStore([thunk]);
。谢谢!
我有几个 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_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。)
我的一个想法是我可以将这两个函数移动到不同的文件中。不幸的是,这样做会极大地破坏我们项目其余部分的组织方式,所以我不愿意这样做,除非它确实是唯一的解决方案。
如何在 functionToTest
的测试中模拟 functionToMock
而不会出现此错误?
一个解决方案就是模拟 functionToMock
。这个问题及其答案解释了如何这样做:How to mock imported named function in Jest when module is unmocked
This answer in particular 解释说,为了让这种方法在您使用像 Babel 这样的转译器时起作用,您可能需要在 functionToTest
(在你的测试之外),像这样:
export const functionToTest = () => async (dispatch) => {
dispatch(exports.functionToMock());
};
你在问题中的例子帮助我修复了一个单独的错误。解决方案是将 thunk
扔进 const mockStore = configureMockStore([thunk]);
。谢谢!