Jest.js NGRX效应测试{ dispatch:错误}

omhiaaxx  于 2023-04-18  发布在  Jest
关注(0)|答案(2)|浏览(121)

我一直在努力让这个工作了几个小时.这是第一个项目,我已经转换到Jest,而不是业力,到目前为止一切顺利.我去写一些测试,我的影响,虽然和无论什么原因,我完全无法测试他们的方式,我会期望.
我想测试的效果是一个非常简单的导航:

@Effect({ dispatch: false })
go$ = this.actions$.pipe(
  ofType(RouterActions.GO),
  tap(
    ({ payload: { path, query: queryParams, extras } }: RouterActions.Go) => {
      this.router.navigate(path, { queryParams, ...extras });
    }
  )
);

我已经注入了一个假路由器,并打算测试它正在调用导航,该测试已经经历了多次迭代试图让它工作,但我目前拥有的是:

describe('Router Effects', () => {
  let actions$: Observable<any>;
  let router: TestRouter;
  let effects: RouterEffects;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        RouterEffects,
        provideMockActions(() => actions$),
        {
          provide: Router,
          useFactory: getRouter
        }
      ]
    });

    actions$ = TestBed.get(Actions);
    router = TestBed.get(Router);
    effects = TestBed.get(RouterEffects);
  });

  describe('go$', () => {
    test('should call router.navigate with the correct path', done => {
      const action = new fromActions.Go({ path: ['some', 'path'] });

      actions$ = hot('-a', { a: action });
      const expected = cold('-b', { b: action });

      effects.go$.subscribe(
        result => {
          console.log('inside subscribe?');
          expect(router.navigate).toHaveBeenCalled();
          console.log('after expect');
          done();
          console.log('after done?');
        },
        done,
        done
      );

      expect(effects.go$).toBeObservable(expected);
    });
  });
});

当我运行该测试时,我在终端中得到以下结果:

FAIL  src/app/store/effects/router.effects.spec.ts (5.832s)
  ● Console

    console.log src/app/store/effects/router.effects.spec.ts:48
      inside subscribe?
    console.log src/app/store/effects/router.effects.spec.ts:50
      after expect
    console.log src/app/store/effects/router.effects.spec.ts:52
      after done?

  ● Router Effects › go$ › should call router.navigate with the correct path

    Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.

我一直在努力弄清楚为什么异步回调没有被调用?我在这里复制了一个最小的repo:https://github.com/BenAychh/example-ngrx-effects-jest和有问题的代码位于这个文件夹https://github.com/BenAychh/example-ngrx-effects-jest/tree/master/src/app/store/effects。如果有人有兴趣在这里帮助我,你应该能够克隆下来,整个仓库,只要运行它,并(希望)看到我所看到的。

7kqas0il

7kqas0il1#

鉴于此效果:

@Injectable()
export class AuthEffects {
    @Effect({ dispatch: false })
    public logoutSuccess$ = this.actions$.pipe(
        ofType(AuthActionTypes.LogoutSuccess),
        tap(() => this.localStorage.removeItem(AUTH_FEATURE_KEY)),
        tap(() => this.router.navigate(['/']))
    );
}

这是我测试dispatch: false效果的方法:

describe('logoutSuccess$', () => {
    it('should navigate and remove related data from local storage', () => {
        const action = new LogoutSuccess;
        actions$ = cold('-a', { a: action });

        expect(effects.logoutSuccess$).toBeObservable(actions$);
        expect(localStorageService.removeItem).toHaveBeenCalledWith(AUTH_FEATURE_KEY);
        expect(router.navigate).toHaveBeenCalledWith(['/']);
    });
});

.toBeObservable(actions$)就能搞定。
基于this answer

vkc1a9a2

vkc1a9a22#

一个小时前偶然发现了这个问题,在搜索了一段时间后,在 jest-marbles 中发现了一个问题,导致我找到了
到满足冲洗
你会用这个

const expected = hot('-');

expect(effect.method$).toBeObservable(expected);

expect(expected).toSatisfyOnFlush(() => {
  // do your verifications here.
  expect(router.navigate).toHaveBeenCalledWith([]);
});

当然,您希望确保 expectedaction 的结尾匹配。

switchMap(() => this.router.navigate([]))

{ dispatch: false }之前
这将导致最终的Observable为

hot('-a', { a: true });

因为switchMap将导致Observable流具有从router.navigate()返回的最新值“真”。
我希望这对未来的观众有所帮助。

相关问题