我正在测试这部史诗https://github.com/zarcode/unsplashapp/blob/master/src/epics/photos.js.问题是当我运行测试时map永远不会发生(我假设这意味着promise 永远不会解决),所以photosSuccess操作也永远不会发生:

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))),
          );
      }),
    );
};

然而,如果我做了requestAction.subscribe个promise ,我就会得到解决,并在控制台日志(log)中得到结果.

Note:只有当我运行这个测试时才会发生这种情况https://github.com/zarcode/unsplashapp/blob/master/src/epics/photos.test.js,应用程序代码工作正常,数据获取正常.

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

推荐答案

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

在try 测试我的异步代码之前,我遇到了很多问题,大多数问题是,在处理已解决的promise 之前,测试断言了预期的行为,需要在event loop的下一个刻度中进行断言,实际上,我是通过将断言放在setImmediate中来实现的,这也可以通过setTimeout实现.

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

还可以使用其他策略,比如async/await,或者您可以解析一个空的promise ,将断言放入then回调,而不是使用setTimeout.请记住,如果在测试流中存在更多promise ,那么在实现所需输出之前,事件循环上将需要更多的勾号.

编辑:实施:

// test
it('produces the photo model', (done) => {
...
// dispatch epic triggering action
store.dispatch(...);
// assertion
setImmediate(() => {
  expect(store.getActions()).toEqual([
  ...
  ]);
  done();
});

React-native相关问答推荐

我们如何才能将我们自己的应用程序(IOS)排除在共享表中?

无法读取 @react-native-async-storage/async-storage 的未定义属性setItem

FlatList 总是增长到 100% 高度

应用管理

自定义单选按钮在react native 中不起作用

使用 React Native 下载数据文件以供离线使用

react-navigation中的React-native android后退按钮

IntelliSense 在第一项后无法在 React Native 样式表中工作

Visual Studio 代码错误:-Failed to start flow Error: Wrong version of Flow. The config specifies version ^0.92.0 but this is version 0.95.1

如何启用 stacktrace react-native run-android 命令?

xcrun:错误:SDK "iphoneos" cannot be located

try 添加包时出现错误duplicate entry:com/google/android/gms/internal/zzble.class

自定义原生基础的选项卡

ScrollView visible Scroll Bar

如何在 Text ReactNative 中包含 TouchableOpacity

更改按钮 colored颜色 onPress(切换功能)

Native Script 与 react native 和 ionic 框架的区别

键盘上方的 React Native 完成按钮

如何从 React-Native 中的另一个类调用函数?

Node.js 在 React-Native 中的作用是什么?