开玩笑测试不会等到传奇结束

Jest test doesnt wait for a saga to end

测试用的笑话, Redux-Saga

假设我有这个故事:

export function* callCreateTemplate({payload}){
try{
  ...
  yield delay(1500)
  ...
}

不要因为这个延迟 (1500) 与 API 有关。

然后,我在 Jest 中有我的测试用例,我用 runSaga 调用传奇:

it('...'), async () => {
   ...
   await runSaga(...);
   expect(dispatchedActions).toHaveLength(3);
}

dispatchedActions 是 mock 的一部分,是一个包含 saga 执行的所有分派操作的数组。

问题是,当我删除 saga 中的 delay(1500) 时,测试用例工作正常,但是当我使用 delay(1500) 执行测试时,延迟后的调度操作不会执行.

如何让测试用例等待saga的执行?

runSaga returns a Task 具有 task.toPromise() 方法的对象。您应该将任务转换为 promise,以便您可以使用 async/await 等待任务完成。

此外,您需要确保 test 案例的 timeout 参数值大于 delay 效果中传递的毫秒数。

import { runSaga } from 'redux-saga';
import { delay, put } from 'redux-saga/effects';

export function* callCreateTemplate({ payload }) {
  yield delay(1500);
  yield put({ type: 'CREATE_TEMPLATE', payload });
}

describe('callCreateTemplate', () => {
  test('should pass', async () => {
    const dispatchedActions: any[] = [];
    await runSaga(
      {
        dispatch: (action) => dispatchedActions.push(action),
        getState: () => ({}),
      },
      callCreateTemplate,
      { payload: 'fake payload' },
    ).toPromise();
    expect(dispatchedActions).toHaveLength(1);
    expect(dispatchedActions).toEqual([{ type: 'CREATE_TEMPLATE', payload: 'fake payload' }]);
  }, 2000);
});

测试结果:

 PASS   redux-saga-examples  packages/redux-saga-examples/src/Whosebug/71787549/index.test.ts
  callCreateTemplate
    ✓ should pass (1508 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.118 s