用玩笑的计时器测试redux-saga防抖动

问题描述 投票:3回答:1

我有一个传奇,侦听模型更新并触发保存到网络,并在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 docsjest 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),最终的jest.runTimersToTime(1500)都会在分派去抖动作之前执行,总是失败。

如何处理这种情况?

javascript reactjs jest redux-saga
1个回答
0
投票

伪造的计时器正确地提前了时间,但是仍然有必要释放事件循环,以便生成器恢复执行,并且只有在我们可以继续执行期望之后才可以执行

关于不使用setTimeout的方法的示例(因为它已经被玩笑所嘲笑):

jest.runTimersToTime(1500);
await Promise.resolve(); // generator resumes execution
expect(dispatched).toEqual([
   IllustrationsActions.apiUpdateGraph('model three')
]);
© www.soinside.com 2019 - 2024. All rights reserved.