NGRX 使用 {dispatch: false } 进行效果测试

Ben*_*dez 6 jestjs ngrx angular

我已经尝试让它工作几个小时了。这是我转换为 Jest 而不是 Karma 的第一个项目,到目前为止一切顺利。我为我的效果编写了一些测试,但无论出于何种原因,我完全无法按照我期望的方式测试它们。

\n\n

我试图测试的效果是一个非常简单的导航效果:

\n\n
@Effect({ dispatch: false })\ngo$ = this.actions$.pipe(\n  ofType(RouterActions.GO),\n  tap(\n    ({ payload: { path, query: queryParams, extras } }: RouterActions.Go) => {\n      this.router.navigate(path, { queryParams, ...extras });\n    }\n  )\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
describe(\'Router Effects\', () => {\n  let actions$: Observable<any>;\n  let router: TestRouter;\n  let effects: RouterEffects;\n  beforeEach(() => {\n    TestBed.configureTestingModule({\n      providers: [\n        RouterEffects,\n        provideMockActions(() => actions$),\n        {\n          provide: Router,\n          useFactory: getRouter\n        }\n      ]\n    });\n\n    actions$ = TestBed.get(Actions);\n    router = TestBed.get(Router);\n    effects = TestBed.get(RouterEffects);\n  });\n\n  describe(\'go$\', () => {\n    test(\'should call router.navigate with the correct path\', done => {\n      const action = new fromActions.Go({ path: [\'some\', \'path\'] });\n\n      actions$ = hot(\'-a\', { a: action });\n      const expected = cold(\'-b\', { b: action });\n\n      effects.go$.subscribe(\n        result => {\n          console.log(\'inside subscribe?\');\n          expect(router.navigate).toHaveBeenCalled();\n          console.log(\'after expect\');\n          done();\n          console.log(\'after done?\');\n        },\n        done,\n        done\n      );\n\n      expect(effects.go$).toBeObservable(expected);\n    });\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
FAIL  src/app/store/effects/router.effects.spec.ts (5.832s)\n  \xe2\x97\x8f Console\n\n    console.log src/app/store/effects/router.effects.spec.ts:48\n      inside subscribe?\n    console.log src/app/store/effects/router.effects.spec.ts:50\n      after expect\n    console.log src/app/store/effects/router.effects.spec.ts:52\n      after done?\n\n  \xe2\x97\x8f Router Effects \xe2\x80\xba go$ \xe2\x80\xba should call router.navigate with the correct path\n\n    Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我一直在绞尽脑汁试图弄清楚为什么异步回调没有被调用?我在这里复制了一个最小的存储库:https://github.com/BenAychh/example-ngrx-effects-jest,有问题的代码位于此文件夹中https://github.com/BenAychh/example-ngrx-effects -jest/tree/master/src/app/store/effects。如果有人有兴趣在这里帮助我,您应该能够克隆整个存储库并运行它并(希望)看到我所看到的内容。

\n

lls*_*mll 4

鉴于这种效果:

@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(['/']))
    );
}
Run Code Online (Sandbox Code Playgroud)

这是我测试效果的方法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(['/']);
    });
});
Run Code Online (Sandbox Code Playgroud)

.toBeObservable(actions$)可以了。

基于这个答案