我正在尝试使用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.
上运行时,出现以下错误?
答案 0 :(得分:0)
问题是您正在使用 redux-thunk 中间件,但是一旦您的诺言得到解决,您就不会调度任何动作(您可以检查如何定义使用 redux-thunk的动作创建者在documentation中。
因此,您需要定义一个动作创建者,该动作创建者使用您的 dummy 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 }));
};
请注意,动作创建者如何接收参数 dispatch (由 redux-thunk 中间件提供),我们使用该函数来分配动作(即简单对象) )。
一旦使用正确的参数调用动作创建者,则应在 it 中返回您的诺言,以便等到诺言得到解决并在 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 中测试失败案例。
您可以看到该解决方案在here中起作用。