测试观察其他史诗的可观察史诗

时间:2017-10-31 13:52:51

标签: reactjs redux rxjs redux-observable

我正在尝试测试一个Redux Observable epic,它会调度一个动作来调用另一个史诗。不知怎的,没有调用被调用的史诗。

让我们说我的史诗看起来像这样;

const getJwtEpic = (action$, store, { api }) =>
  action$.ofType('GET_JWT_REQUEST')
    .switchMap(() => api.getJWT()
      .map(response => {
        if (response.errorCode > 0) {
          return {
            type: 'GET_JWT_FAILURE',
            error: { code: response.errorCode, message: response.errorMessage },
          };
        }

        return {
          type: 'GET_JWT_SUCCESS',
          idToken: response.id_token,
        };
      })
    );

const bootstrapEpic = (action$, store, { api }) =>
  action$.ofType('BOOTSTRAP')
    .switchMap(() =>
      action$.filter(({ type }) => ['GET_JWT_SUCCESS', 'GET_JWT_FAILURE'].indexOf(type) !== -1)
        .take(1)
        .mergeMap(action => {
          if (action.type === 'GET_JWT_FAILURE') {
            return Observable.of({ type: 'BOOTSTRAP_FAILURE' });
          }

          return api.getProfileInfo()
            .map(({ profile }) => ({
              type: 'BOOTSTRAP_SUCCESS', profile,
            }));
        })
        .startWith({ type: 'GET_JWT_REQUEST' })
    );

当我尝试使用以下代码测试Jest中的bootstrapEpic时;

const response = {};

const api = { getJWT: jest.fn() };
api.getJWT.mockReturnValue(Promise.resolve(response));

const action$ = ActionsObservable.of(actions.bootstrap());
const epic$ = epics.bootstrapEpic(action$, null, { api });

const result = await epic$.toArray().toPromise();
console.log(result);

console.log来电给我以下输出;

[ { type: 'GET_JWT_REQUEST' } ]

某种程度上根本没有调用getJwtEpic。我想这与action$ observable没有调度GET_JWT_REQUEST动作有关,但我无法弄清楚原因。所有的帮助都是如此受欢迎!

1 个答案:

答案 0 :(得分:3)

假设actions.rehydrate()返回BOOTSTRAP类型的操作且gigya内容为拼写错误,

getJwtEpic未被调用,因为您没有自己调用它当您通过手动调用它们来测试epics时,它只是一个返回Observable的函数,不知道中间件或其他任何东西。连接getJwtEpic作为根史诗的一部分,并为其提供(action$, store)的管道是中间件的一部分,您在测试中不会使用它。

这是正确的方法,在没有redux / middleware的情况下单独测试它们。所以你通过提供动作和依赖关系来单独测试每个史诗,然后断言它发出的动作以及它调用的依赖关系。

您将测试成功路径:

const api = {
  getProfileInfo: () => Observable.of({ profile: 'mock profile' })
};
const action$ = ActionsObservable.of(
  actions.rehydrate(),
  { type: 'GET_JWT_SUCCESS', idToken: 'mock token' }
);

const epic$ = epics.bootstrapEpic(action$, null, { api });

const result = await epic$.toArray().toPromise();

expect(result).toEqual([
  { type: 'GET_JWT_REQUEST' },
  { type: 'BOOTSTRAP_SUCCESS', profile: 'mock profile' }
]);

然后你将通过做同样的事情测试另一个测试中的失败路径,除了给它GET_JWT_FAILURE而不是GET_JWT_SUCCESS。然后,您也可以单独测试getJwtEpic

顺便说一下,ofType接受任意数量的类型,因此您可以action$.ofType('GET_JWT_SUCCESS', 'GET_JWT_FAILURE')