代码之家  ›  专栏  ›  技术社区  ›  Alex Verzea

NgRx弹珠效果测试返回奇怪错误

  •  1
  • Alex Verzea  · 技术社区  · 7 年前

    我有一个使用NgRx效果的Angular 5应用程序。其中一种效果通过将用户输入的数据传递到NodeJS后端来处理网站注册。效果完全符合预期,但当我试图用弹珠对其进行单元测试时,我得到了一个奇怪的错误。

    这就是效果:

    @Effect()
      authSignup$ = this.actions$
        .ofType(AuthActions.TRY_SIGNUP)
        .switchMap((signUpData: {
          first_name: string,
          last_name: string,
          username: string,
          password: string,
          type: string,
          agreement: boolean
        }) =>
          this.httpClient.post(
          '/custom-endpoint',
          {
            first_name: signUpData.first_name,
            last_name: signUpData.last_name,
            username: signUpData.username,
            password: signUpData.password,
            type: signUpData.type,
            agreement: signUpData.agreement
          },
          {
            headers: new HttpHeaders({
              'Content-Type':  'application/json'
            })
          })
          .map((res) => {
            return new AuthActions.SuccessfulSignup();
          })
          .catch((error: {reason: string}) => {
            return Observable.of(new AuthActions.UnsuccessfulSignup({reason: error.reason}))
          })
        );
    

    这是大理石的单元测试。它遵循托德·格言的NgRx效果测试指南。

    export class TestActions extends Actions {
      constructor() {
        super(empty());
      }
    
      set stream(source: Observable<any>) {
        this.source = source;
      }
    }
    
    export function getTestActions() {
      return new TestActions();
    }
    
    fdescribe('AuthEffects', () => {
    
      let actions$: TestActions;
      let effects: fromEffects.AuthEffects;
    
      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [
            CookieModule.forRoot(),
            StoreModule.forRoot({...fromGlobal.reducers}),
            RouterTestingModule,
            HttpClientTestingModule
          ],
          providers: [
            fromEffects.AuthEffects,
            CookieAesService,
            { provide: Actions, useFactory: getTestActions },
          ],
        });
        actions$ = TestBed.get(Actions);
        effects = TestBed.get(fromEffects.AuthEffects);
      });
    
      it('should attempt to Sign Up the user', () => {
        const trySignup = new fromActions.TrySignup({
          first_name: 'test',
          last_name: 'test',
          password: 'test',
          username: 'test@test.com',
          type: 'test',
          agreement: false
        });
        const unsuccessfulSignup = new fromActions.UnsuccessfulSignup({ reason: 'test' });
    
        actions$.stream = hot('a', { a: trySignup });
        const expected = cold('b', { b: unsuccessfulSignup });
        expect(effects.authSignup$).toBeObservable(expected);
      });
    });
    

    最后,这是我在因果报应中的错误:

    Expected $.length = 0 to equal 1.
    Expected $[0] = undefined to equal Object({ frame: 0, notification: Notification({ kind: 'N', value: UnsuccessfulSignup({ payload: Object({ reason: 'test' }), type: 'UNSUCCESSFUL_SIGNUP' }), error: undefined, hasValue: true }) }).
    

    我从这个相当隐晦的错误信息推断 trySignup 行动被启动了,但没有被取消 unsuccessfulSignup 行动有人知道为什么会这样吗?

    谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   Tyler Padley    7 年前

    亚历克斯,

    您的switchMap将流切换到 http.post 流,而你不是存根或返回。您需要从 HttpClientTestingModule 第一个 catch 事件将被触发。

    有关示例,请参见下面的链接:

    https://medium.com/@Jestfer/testing-http-requests-in-angular-with-httpclienttestingmodule-3880ceac74cf