如何测试使用 setTimeout 调用另一个动作的异步动作创建者
How do I test an async action creator that calls another action with setTimeout
我有以下显示通知然后将其删除的操作,我正在尝试为其编写单元测试,但我似乎无法弄清楚如何模拟 setTimeout。
export const addNotification = (text, notificationType = 'success', time = 4000) => {
return (dispatch, getState) =>{
let newId = new Date().getTime();
dispatch({
type: 'ADD_NOTIFICATION',
notificationType,
text,
id: newId
});
setTimeout(()=>{
dispatch(removeNotification(newId))
}, time)
}
};
export const removeNotification = (id) => (
{
type: 'REMOVE_NOTIFICATION',
id
});
根据 redux 网站上关于异步测试的教程,我想出了以下测试:
import * as actions from '../../client/actions/notifyActionCreator'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);
describe('actions', ()=>{
it('should create an action to add a notification and then remove it', ()=>{
const store = mockStore({ notifications:[] });
const text = 'test action';
const notificationType = 'success';
const time = 4000;
const newId = new Date().getTime();
const expectedActions = [{
type: 'ADD_NOTIFICATION',
notificationType,
text,
id: newId
},{
type: 'REMOVE_NOTIFICATION',
id: newId
}];
return store.dispatch(actions.addNotification(text,notificationType,time))
.then(() => {
expect(store.getActions()).toEqual(expectedActions)
});
});
});
现在它只是抛出一个错误 Cannot read 属性 'then' of undefined at store.dispatch,任何帮助将不胜感激。
首先,因为你的 action creator 没有 return 任何东西,当你调用 store.dispatch(actions.addNotification())
它时 returns undefined
这就是你得到错误的原因Cannot read property 'then' of undefined
。要使用 .then()
它应该 return 一个承诺。
因此,您应该修复动作创建者或测试以反映动作创建者实际执行的操作。为了让你的测试通过,你可以把你的测试改成这样:
// set up jest's fake timers so you don't actually have to wait 4s
jest.useFakeTimers();
store.dispatch(actions.addNotification(text,notificationType,time));
jest.runAllTimers();
expect(store.getActions()).toEqual(expectedActions);
另一种选择是使用详述的策略in the Jest docs。
// receive a function as argument
test('should create an action to add a notification and then remove it', (done)=>{
// ...
store.dispatch(actions.addNotification(text,notificationType,time));
setTimeout(() => {
expect(store.getActions()).toEqual(expectedActions);
done();
}, time);
});
当使用这个策略时,Jest 将等待 done()
被调用,否则它会在完成测试体执行时认为测试结束。
我有以下显示通知然后将其删除的操作,我正在尝试为其编写单元测试,但我似乎无法弄清楚如何模拟 setTimeout。
export const addNotification = (text, notificationType = 'success', time = 4000) => {
return (dispatch, getState) =>{
let newId = new Date().getTime();
dispatch({
type: 'ADD_NOTIFICATION',
notificationType,
text,
id: newId
});
setTimeout(()=>{
dispatch(removeNotification(newId))
}, time)
}
};
export const removeNotification = (id) => (
{
type: 'REMOVE_NOTIFICATION',
id
});
根据 redux 网站上关于异步测试的教程,我想出了以下测试:
import * as actions from '../../client/actions/notifyActionCreator'
import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);
describe('actions', ()=>{
it('should create an action to add a notification and then remove it', ()=>{
const store = mockStore({ notifications:[] });
const text = 'test action';
const notificationType = 'success';
const time = 4000;
const newId = new Date().getTime();
const expectedActions = [{
type: 'ADD_NOTIFICATION',
notificationType,
text,
id: newId
},{
type: 'REMOVE_NOTIFICATION',
id: newId
}];
return store.dispatch(actions.addNotification(text,notificationType,time))
.then(() => {
expect(store.getActions()).toEqual(expectedActions)
});
});
});
现在它只是抛出一个错误 Cannot read 属性 'then' of undefined at store.dispatch,任何帮助将不胜感激。
首先,因为你的 action creator 没有 return 任何东西,当你调用 store.dispatch(actions.addNotification())
它时 returns undefined
这就是你得到错误的原因Cannot read property 'then' of undefined
。要使用 .then()
它应该 return 一个承诺。
因此,您应该修复动作创建者或测试以反映动作创建者实际执行的操作。为了让你的测试通过,你可以把你的测试改成这样:
// set up jest's fake timers so you don't actually have to wait 4s
jest.useFakeTimers();
store.dispatch(actions.addNotification(text,notificationType,time));
jest.runAllTimers();
expect(store.getActions()).toEqual(expectedActions);
另一种选择是使用详述的策略in the Jest docs。
// receive a function as argument
test('should create an action to add a notification and then remove it', (done)=>{
// ...
store.dispatch(actions.addNotification(text,notificationType,time));
setTimeout(() => {
expect(store.getActions()).toEqual(expectedActions);
done();
}, time);
});
当使用这个策略时,Jest 将等待 done()
被调用,否则它会在完成测试体执行时认为测试结束。