我正在尝试测试一个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
动作有关,但我无法弄清楚原因。所有的帮助都是如此受欢迎!
答案 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')