Reactjs redux可观察承诺在单元测试中未得到解决

Reactjs redux可观察承诺在单元测试中未得到解决,reactjs,unit-testing,react-native,jestjs,redux-observable,Reactjs,Unit Testing,React Native,Jestjs,Redux Observable,我正在尝试测试这部史诗。问题是当我运行测试时,map从未发生过(我假设这意味着承诺永远不会解决),所以photosuccess操作也从未发生过: export const loadPhotosToList = (action$: Observable<Action>, state$: Object): Observable<Action> => { const state = (photosFilter: PhotosFilter) => state$.

我正在尝试测试这部史诗。问题是当我运行测试时,
map
从未发生过(我假设这意味着承诺永远不会解决),所以
photosuccess
操作也从未发生过:

export const loadPhotosToList = (action$: Observable<Action>, state$: 
Object): Observable<Action> => {
  const state = (photosFilter: PhotosFilter) => state$.value.photos[photosFilter];
  return action$
  // .ofType(ACTION.FETCH_PHOTOS_REQUESTED)
    .pipe(
      filter((a: Action) =>
        a.type === ACTION.FETCH_PHOTOS_REQUESTED &&
        ((state(a.filter).loadingState === 'idle' && !state(a.filter).isLastPage) || a.refresh)),
      switchMap((a) => {
        const nextPage = !a.refresh ? state(a.filter).lastLoadedPage + 1 : 1;
        const loadingAction = of(photosActions.photosLoading(a.filter, a.refresh));
        const request = api.fetchPhotos({
          page: nextPage,
          per_page: perPage,
          order_by: a.filter,
        });
        const requestAction = from(request)
          .pipe(
            // tap(data => { console.log("data", data); }),
            map(data =>
              photosActions.photosSuccess(
                data,
                a.filter,
                nextPage,
                data.length < perPage,
                a.refresh,
              )),
            catchError(e => of(photosActions.photosFail(e.message, a.filter))),
          );
        // requestAction.subscribe(x => console.log("-------",x));
        return loadingAction
          .pipe(
            concat(requestAction),
            takeUntil(action$
              .pipe(filter(futureAction => futureAction.type === ACTION.FETCH_PHOTOS_REQUESTED))),
          );
      }),
    );
};
export const loadphototolist=(操作$:可观察,应用程序代码工作正常,数据获取正常


问题是:如何正确编写此测试?

在测试异步代码时,请记住您需要使用不同的策略,如中所述

在尝试测试我的异步代码之前,我遇到了很多问题,大多数问题是测试在处理已解决的承诺之前断言了预期的行为,并且需要在下一个勾号中进行断言,实际上我是通过将断言放在
setImmediate
中来实现的这也可以通过设置超时来实现

从jest的文档中,您可以更改测试并通过
done
回调,按正常方式分派触发操作,但将断言放在一个
setTimeout
回调中,超时1 ms,只允许处理已解析的承诺,然后将调用回调并断言所需状态。

可以使用其他策略,如
async/await
,或者您可以不使用
setTimeout
,而是解析一个空承诺,并将断言放入
然后
回调中。请记住,如果测试流中存在更多承诺,则需要在事件循环上进行更多的标记,直到获得所需的输出我被认为是被断言的

编辑:实施:

//测试
它('生成照片模型',(完成)=>{
...
//调度epic触发动作
存储、发送(…);
//断言
setImmediate(()=>{
expect(store.getActions()).toEqual([
...
]);
完成();
});

当我运行您的测试套件时,我得到了
无效的变量访问:console
并且所有6个都失败了,您知道为什么吗?您可以尝试用return Observable替换return loadingAction。fromPromise(loadingAction)?@TarunLalwani可能与节点版本有关,我正在v9.2上运行它。0@dentemm
photoActions.photoLoading(a.filter,a.refresh)
是一个对象,而不是承诺,因此返回可观察的。fromPromise(loadingAction)或from(loadingAction)rxjs v6抛出了一个此类错误:
TypeError:您在预期流的位置提供了一个无效的对象。您可以提供一个可观察的、承诺的、数组的或可观察的。
@zarcode,现在可以工作了,我在
10.1.0
,可能是因为您在问题中有了repo,而不是给出了理论上的答案,如果你能修改测试并在你的答案中更新,那就太好了。我试过你的建议,但没能修改。所以最好你检查一下。我不同意“取而代之”,因为如果不解释问题发生的原因以及如何解决问题,我就没有必要去解决问题,这对每个人来说都是最好的学习方式,包括对我来说。但是如果问题持续存在,帮助更多也没问题,实际上会更快,我在这篇文章中发布了解决方案。正如我在回答中所写的那样,通过
done
callback,它将
jest
公开,在
setImmediate
回调中断言,并在其内部调用
done
,我将更新答案以显示更直观的实现。