0

我需要为我在这部loadEpic史诗中使用的自定义运算符编写大理石测试 - 这有助于我避免INITIALiZE有时动作被调度到较晚并且我得到的问题LOAD_FAILURE

loadEpic: Epic<ExamManagementAction, ExamManagementAction, RootState> = (
    action$,
    state$
  ) =>
    action$.pipe(
      filter(isActionOf(load)),
      waitFor(state$),
      switchMap(() =>
        this.load(state$).pipe(
          map(loadSuccess),
          catchError(error => of(loadFailure({ error })))
        )
      )
    );

这就是我编写waitFor运行良好的运算符的方式:

const waitFor = <T>(
  state$: Observable<RootState>
): OperatorFunction<T, T> => source$ =>
  source$.pipe(
    switchMap(value =>
      state$.pipe(
        filter(state => state.navigation.initialized),
        take(1),
        mapTo(value)
      )
    )
  );

你能帮我用rxjs-marbles/jest或任何类似的方法编写这个测试吗?非常感谢!

4

1 回答 1

0

您描述了三个事件流:

  1. 状态(用简单的对象模拟它们)
  2. 动作(同样,您可以使用任何 JS 值作为模拟)
  3. 过滤的动作(与 2 中的相同对象)

然后,您希望您的操作员使用 toBeObservable 匹配器将 2 转换为 3。而已。

  it('should reject given values until navigation is initialized', () => {
    const state$ = hot('   -i--u--u-i--  ', {u: {navigation: {initialized: false}}, i: {navigation: {initialized: true}}});
    const action$ = hot('  v----v--v---  ', {v: load});
    const expect$ = cold(' -v-------v--  ', {v: load});

    expect(action$.pipe(waitFor(state$))).toBeObservable(expect$);
  });

请注意我如何格式化我的代码,以便在另一个流下描述一个流。它确实有助于处理长序列的事件。

您还可以为边缘情况编写单独的规范。这取决于您要测试的行为。

于 2019-10-25T13:25:50.057 回答