我正在尝试使用 redux-mock-store 在我的React
应用程序中测试一些异步代码。
const configureMockStore = require('redux-mock-store').default;
const thunk = require("redux-thunk").default;
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
const dummy = () => {
// Mock Ajax call
return new Promise((resolve, reject) => {
setTimeout(() => resolve({data: 'data'}), 200)
})
};
describe("Redux Mock Store", () => {
it("Test Dummy Ajax call", () => {
const expectedActions = [
{ type: "SUCCESS", payload: "success" },
{ type: "FAILURE", error: { Error: "Error" } }
];
const store = mockStore({});
store.dispatch(dummy().then(() => {
expect(store.getActions()).toEqual(expectedActions)
}).catch(error => { console.log(error) }))
});
});
我正在使用Jest
来运行此测试。我在测试上运行时出现以下错误Actions must be plain objects. Use custom middleware for async actions.
这里出了什么问题?
问题是你正在使用redux-thunk中间件,但一旦你的承诺解决,你就不会调度任何操作(你可以在文档中检查如何定义使用redux-thunk的操作创建者)。
因此,您需要定义一个操作创建器,该创建器使用您的虚拟ajax 请求并在完成后调度操作:
const dummy = () => {
// Mock Ajax call
// Note that you are not capturing any error in here and you are not
// calling the reject method, so your *catch* clausule will never be
// executed.
return new Promise((resolve, reject) => {
setTimeout(() => resolve({ data: 'success' }), 200);
});
};
const actionCreator = () => (dispatch) => {
return dummy()
.then(payload => dispatch({ type: 'SUCCESS', payload }))
.catch(error => dispatch({ type: 'FAILURE', error }));
};
请注意操作创建者如何接收参数调度(由redux-thunk中间件提供),我们使用该函数来调度我们的操作(即简单对象)。
使用正确的参数调用操作创建者后,您应该在it中返回您的 promise,以便它等到承诺解析并执行then语句中的期望:
describe('Redux Mock Store', () => {
it('Test Dummy Ajax call', () => {
const expectedActions = [
{ type: 'SUCCESS', payload: { data: 'success' } },
];
const store = mockStore({});
return store.dispatch(actionCreator()).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
});
此外,请注意,在初始测试中,您希望调度两个操作,但您只调用操作创建者一次。您应该在另一个it中测试失败案例。
您可以在此处看到解决方案的工作原理。