如何测试Redux可观察史诗的竞赛条件 [英] How to test race condition of a redux observable epic

查看:121
本文介绍了如何测试Redux可观察史诗的竞赛条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例,需要取消Ajax调用并在史诗级中执行其他操作.可在Redux上查看的文档中有一个示例完全适合我的需求.但是,当我尝试在我的史诗中测试赛车状况时,取消"似乎无效.

I have a use case where I need to cancel an Ajax call and do something else in an epic. There's an example in the redux-observable doc which fits my need exactly. However, when I try to test the racing condition in my epic, the "cancelation" doesn't seem to work.

示例代码如下:

import { ajax } from 'rxjs/ajax';

const fetchUserEpic = action$ => action$.pipe(
  ofType(FETCH_USER),
  mergeMap(action => race(
    ajax.getJSON(`/api/users/${action.payload}`).pipe(
      map(response => fetchUserFulfilled(response))
    ),
    action$.pipe(
      ofType(FETCH_USER_CANCELLED),
      map(() => incrementCounter()),
      take(1)
    )
  ))
);

我的史诗与上面的示例具有相同的结构,就像:

My epic has the same structure as the example above, which is like:

initViewsEpic = (action$, state$, { ajaxGet }) => action$
  .ofType(INIT_VIEWS)
  .pipe(
    mergeMap(() => race(
      ajaxGet('/api/views/...')
        .pipe(
          switchMap(response => of(
            initViewsFulFilled(response),
            taskCompleted(INIT_VIEWS),
          )),
          startWith(taskInProgress(INIT_VIEWS)),
          catchError(error => of(
             notification(),
             taskCompleted(INIT_VIEWS),
           )),
        ),
      action$.pipe(
        ofType(INIT_VIEWS_CANCEL),
        map(() => taskCompleted(INIT_VIEWS),
        take(1),
      ),
    )),
  );

我的测试就像:

test('should ignore the ajax call response when INIT_VIEWS_CANCEL action is fired', (done) => {
    const action$ = ActionsObservable.of({ type: 'INIT_VIEWS' }, { type: 'INIT_VIEWS_CANCEL' });
    const ajaxGet = () => timer(3000);

   initViewsEpic(action$, state$, { ajaxGet })
      .pipe(toArray()).subscribe((actions) => {
        expect(actions).toEqual([
          {
            type: 'TASK_IN_PROGRESS',
            payload: { id: 'INIT_VIEWS' },
          },
          {
            type: 'TASK_COMPLETED',
            payload: { id: 'INIT_VIEWS' },
          },
        ]);
        done();
      });
  });

我认为,由于INIT_VIEWS_CANCEL动作同步地跟随INIT_VIEWS动作,因此它应该赢得" ajaxGet并且不应有任何initViewsFulFilled熄灭.但是此测试的结果始终返回initViewsFulFilled作为我的史诗的第二个输出动作(我正在通过玩笑来测试史诗).

I suppose that since the INIT_VIEWS_CANCEL action follows the INIT_VIEWS action synchronously, it should "win" the ajaxGet and there should not be any initViewsFulFilled goes out. But the result of this test always returns initViewsFulFilled as the second output action of my epic (I am using jest to test the epic).

我在测试中做错了什么吗?如果是这样,我该如何在可观看Redux的史诗中正确测试此比赛条件?

Is there anything I did wrong in my test? If so, how can I test this race condition in a redux-observable epic properly?

推荐答案

我要提出一个建议,以测试redux可观察的史诗( 我所做的)-在rxjs/testing 中使用 TestScheduler.这样我们就不必花时间处理其他测试框架的ascyn事情了

I will say I'm going to give a suggestion to test redux observable epics (that's what I've done) -- Use TestScheduler in rxjs/testing. So that we don't have to scratch the head dealing with ascyn things of other test frameworks

希望这可以帮助遇到与我相同的问题的人.

Hope this can help someone who have the same problem as I did.

这篇关于如何测试Redux可观察史诗的竞赛条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆