我有一个传奇,它监听模型更新并触发保存到网络,并以 1 秒去抖动:
export default function* graphModelUpdate() {
const modelChangeDebounceTime = 1000;
let task;
while (true) {
const action = yield take(IllustrationsActions.GRAPH_MODEL_CHANGED);
if (task) {
yield cancel(task);
}
task = yield fork(function* (payload) {
yield call(delay, modelChangeDebounceTime);
yield put(IllustrationsActions.apiUpdateGraph(payload));
}, action.payload);
}
}
然后我有这个测试,按照redux-saga docs写的和jest docs regarding timers ,测试传奇的效果而不是其实现:
jest.useFakeTimers();
describe('graphModelUpdate saga', () => {
let dispatched;
let mockState;
let subscribers = [];
const emitAction = (action) => {
subscribers.forEach(cb => cb(action));
};
const options = {
subscribe: callback => {
subscribers.push(callback);
return () => subscribers = subscribers.filter(cb => cb !== callback);
},
dispatch: (action) => dispatched.push(action),
getState: () => mockState
};
beforeEach(() => {
dispatched = [];
mockState = {};
});
it('should listen for IllustrationsActions.GRAPH_MODEL_CHANGED and dispatch IllustrationsActions.apiUpdateGraph, debounced by 1 second', () => {
runSaga(options, graphModelUpdate);
emitAction(IllustrationsActions.graphModelChanged('model one'));
emitAction(IllustrationsActions.graphModelChanged('model two'));
emitAction(IllustrationsActions.graphModelChanged('model three'));
expect(dispatched).toEqual([]);
jest.runTimersToTime(1500);
expect(dispatched).toEqual([
IllustrationsActions.apiUpdateGraph('model three')
]);
});
});
问题是,由于传奇使用 fork
异步运行,最终的expect
在调度 debounced 操作之前执行,无论经过多少虚假时间 ( jest.runTimersToTime(1500)
),都会导致测试失败。
我该如何处理这种情况?
最佳答案
假定时器正确地提前了时间,但仍然需要释放事件循环,以便生成器恢复执行,并且只有在我们可以继续执行预期之后
有关如何在不使用 setTimeout
的情况下执行此操作的示例(因为它已被 Jest mock ):
jest.runTimersToTime(1500);
await Promise.resolve(); // generator resumes execution
expect(dispatched).toEqual([
IllustrationsActions.apiUpdateGraph('model three')
]);
关于javascript - 使用 jest fake 计时器测试 redux-saga debounce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49232702/