NgRx Marbles Тестирование эффекта возвращает странную ошибку

У меня есть приложение Angular 5, которое использует эффекты NgRx. Один из эффектов обрабатывает регистрацию на веб-сайт, передавая данные, введенные пользователем, в серверную часть NodeJS. Эффект работает точно так, как задумано, но когда я пытаюсь протестировать его с помощью Marbles, я получаю странную ошибку.

Это Эффект:

@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: '[email protected]',
      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);
  });
});

Наконец, это ошибка, которую я получаю в Karma:

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. Кто-нибудь знает, почему это может происходить?

Спасибо!


person Alex Verzea    schedule 04.06.2018    source источник
comment
Привет, Алекс! Я тоже столкнулся с той же ошибкой. Удалось ли вам это решить?   -  person Bharat    schedule 09.07.2018
comment
@Bharat Привет, нет, я не смог это исправить. По словам других, которые сообщили об этой ошибке в StackOverflow, может быть ошибка с горячими и / или холодными Observables в библиотеке, которая вызывает это. В настоящее время у меня нет дополнительной информации.   -  person Alex Verzea    schedule 09.07.2018


Ответы (1)


Алекс,

Ваш switchMap переключает поток на поток http.post, который вы не заглушаете и не возвращаете. Для запуска события catch необходимо сначала выдать ошибку из HttpClientTestingModule.

См. Ссылку ниже для примера:

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

person Tyler Padley    schedule 11.04.2019