【问题标题】:React + Redux-Observable Timeout Marble TestingReact + Redux-Observable Timeout Marble 测试
【发布时间】:2018-11-22 09:43:34
【问题描述】:

我正在使用 React 和 Redux Observables 创建一个 Web 应用程序,我想为我的史诗之一的超时场景创建一个单元测试。

这是史诗:

export const loginUserEpic = (action$: ActionsObservable<any>, store, { ajax, scheduler }): Observable<Action> =>
  action$.pipe(
    ofType<LoginAction>(LoginActionTypes.LOGIN_ACTION),
    switchMap((action: LoginAction) =>
      ajax({
        url,
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: { email: action.payload.username, password: action.payload.password },
      }).pipe(
        timeout(timeoutValue, scheduler),
        map((response: AjaxResponse) => loginSuccess(response.response.token)),
        catchError((error: Error) => of(loginFailed(error))),
      ),
    ),
  );

这是我的测试:

  it('should handle a timeout error', () => {
    // My current timeout value is 20 millseconds
    const inputMarble = '------a';
    const inputValues = {
      a: login('fake-user', 'fake-password'),
    };

    const outputMarble = '--b';
    const outputValues = {
      b: loginFailed(new Error('timeout')),
    };

    const ajaxMock = jest.fn().mockReturnValue(of({ response: { token: 'fake-token' } }));
    const action$ = new ActionsObservable<Action>(ts.createHotObservable(inputMarble, inputValues));
    const outputAction = loginUserEpic(action$, undefined, { ajax: ajaxMock, scheduler: ts });

    // I am not sure what error to expect here...
    ts.expectObservable(outputAction).toBe(outputMarble, outputValues);
    ts.flush();
    expect(ajaxMock).toHaveBeenCalled();
  });

我的预期是 Epic 会抛出超时错误,因为我的超时值为 20 毫秒,而观察者在发出值之前延迟了 60 毫秒。然后我会接受这个错误并最终比较它以使测试通过。

很遗憾,没有抛出超时错误。我做错了吗?

【问题讨论】:

    标签: reactjs rxjs redux-observable


    【解决方案1】:

    在调用 ajax() 后,您在链中使用 timeout,它只返回 of({ ... }) (ajaxMock),因此永远不会触发 timeout,因为 of 会立即发出。

    如果您想测试timeout 运算符,您需要将delay 添加到ajaxMock

    const ajaxMock = () => of({ response: { token: 'fake-token' } }).pipe(delay(30, ts));
    

    这是你的演示:https://stackblitz.com/edit/rxjs6-demo-pha4qp?file=index.ts

    如果登录请求从 60 开始,并且您添加 30 延迟,那么在 80 您将收到 TimeoutError。

    [0: Object
      frame: 80
      notification: Notification
      error: undefined
      hasValue: true
      kind: "N"
      value: Object
        error: Error
          message: "Timeout has occurred"
          name: "TimeoutError"
    ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 2021-11-13
      • 2019-01-23
      • 2021-05-27
      • 2019-03-19
      • 2020-05-17
      • 2019-03-22
      相关资源
      最近更新 更多