Тестирование эффекта NGRX с задержкой - PullRequest
0 голосов
/ 29 января 2019

Я хочу проверить эффект, который работает следующим образом:

  1. Эффект запускается, если было отправлено действие LoadEntriesSucces
  2. Ожидание 5 секунд
  3. Через 5 секундпередает http запрос отправляется
  4. При получении ответа отправляется новое действие (в зависимости от того, был ли ответ успешным или ошибочным).

Код эффекта выглядит следующим образом:

  @Effect()
  continuePollingEntries$ = this.actions$.pipe(
    ofType(SubnetBrowserApiActions.SubnetBrowserApiActionTypes.LoadEntriesSucces),
    delay(5000),
    switchMap(() => {
      return this.subnetBrowserService.getSubnetEntries().pipe(
        map((entries) => {
          return new SubnetBrowserApiActions.LoadEntriesSucces({ entries });
        }),
        catchError((error) => {
          return of(new SubnetBrowserApiActions.LoadEntriesFailure({ error }));
        }),
      );
    }),
  );

Я хочу проверить, отправляется ли эффект через 5 секунд:

it('should dispatch action after 5 seconds', () => {
  const entries: SubnetEntry[] = [{
    type: 'type',
    userText: 'userText',
    ipAddress: '0.0.0.0'
  }];

  const action = new SubnetBrowserApiActions.LoadEntriesSucces({entries});
  const completion = new SubnetBrowserApiActions.LoadEntriesSucces({entries});

  actions$ = hot('-a', { a: action });
  const response = cold('-a', {a: entries});
  const expected = cold('- 5s b ', { b: completion });

  subnetBrowserService.getSubnetEntries = () => (response);

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

Однако этот тест не работает для меня.Результат теста выглядит следующим образом:

Expected $.length = 0 to equal 3.
Expected $[0] = undefined to equal Object({ frame: 20, notification: Notification({ kind: 'N', value: undefined, error: undefined, hasValue: true }) }).
Expected $[1] = undefined to equal Object({ frame: 30, notification: Notification({ kind: 'N', value: undefined, error: undefined, hasValue: true }) }).
Expected $[2] = undefined to equal Object({ frame: 50, notification: Notification({ kind: 'N', value: LoadEntriesSucces({ payload: Object({ entries: [ Object({ type: 'type', userText: 'userText', ipAddress: '0.0.0.0' }) ] }), type: '[Subnet Browser API] Load Entries Succes' }), error: undefined, hasValue: true }) }).

Что я должен сделать, чтобы этот тест работал?

Ответы [ 3 ]

0 голосов
/ 29 января 2019

Вторая запись не работает с jasmine-marbles, вместо нее используйте тире:

 const expected = cold('------b ', { b: completion });
0 голосов
/ 02 февраля 2019

Вам нужно будет сделать 3 вещи

1- Внутри вашего beforeEach вам необходимо переопределить внутренний планировщик RxJs следующим образом:

    import { async } from 'rxjs/internal/scheduler/async';
    import { cold, hot, getTestScheduler } from 'jasmine-marbles';
    beforeEach(() => {.....
        const testScheduler = getTestScheduler();
        async.schedule = (work, delay, state) => testScheduler.schedule(work, delay, state);
})

2- Заменить задержку,с задержкой при следующем: delayWhen(_x => (true ? interval(50) : of(undefined)))

3 - Использовать кадры, я не совсем уверен, как использовать для этого секунды, поэтому я использовал кадры.Каждый кадр 10 мс.Так, например, моя задержка выше составляет 50 мс, а мой кадр -b, то есть ожидаемые 10 мс + мне потребовалось еще 50 мс, так что это равняется дополнительным 5 кадрам, которые были ------ b, следующим образом:

const expected = cold('------b ', { b: outcome });
0 голосов
/ 29 января 2019

Вы можете использовать обратный вызов done от Жасмин

it('should dispatch action after 5 seconds', (done) => {
  const resMock = 'resMock';
  const entries: SubnetEntry[] = [{
    type: 'type',
    userText: 'userText',
    ipAddress: '0.0.0.0'
  }];

  const action = new SubnetBrowserApiActions.LoadEntriesSucces({entries});
  const completion = new SubnetBrowserApiActions.LoadEntriesSucces({entries});

  actions$ = hot('-a', { a: action });
  const response = cold('-a', {a: entries});
  const expected = cold('- 5s b ', { b: completion });

  subnetBrowserService.getSubnetEntries = () => (response);
  effects.continuePollingEntries$.subscribe((res)=>{
    expect(res).toEqual(resMock);
    done()
  })
});
...