Как проверить расовое состояние наблюдаемой эпопеи - PullRequest
0 голосов
/ 16 октября 2018

У меня есть сценарий использования, когда мне нужно отменить вызов Ajax и сделать что-то еще в эпосе.Есть пример в документируемом документообороте, который точно соответствует моим потребностям.Однако, когда я пытаюсь проверить условия гонки в моем эпосе, «отмена», похоже, не работает.

Пример кода выглядит так:

import { ajax } from 'rxjs/ajax';

const fetchUserEpic = action$ => action$.pipe(
  ofType(FETCH_USER),
  mergeMap(action => race(
    ajax.getJSON(`/api/users/${action.payload}`).pipe(
      map(response => fetchUserFulfilled(response))
    ),
    action$.pipe(
      ofType(FETCH_USER_CANCELLED),
      map(() => incrementCounter()),
      take(1)
    )
  ))
);

Моя эпопея имеет ту же структуру, что и пример выше, например:

initViewsEpic = (action$, state$, { ajaxGet }) => action$
  .ofType(INIT_VIEWS)
  .pipe(
    mergeMap(() => race(
      ajaxGet('/api/views/...')
        .pipe(
          switchMap(response => of(
            initViewsFulFilled(response),
            taskCompleted(INIT_VIEWS),
          )),
          startWith(taskInProgress(INIT_VIEWS)),
          catchError(error => of(
             notification(),
             taskCompleted(INIT_VIEWS),
           )),
        ),
      action$.pipe(
        ofType(INIT_VIEWS_CANCEL),
        map(() => taskCompleted(INIT_VIEWS),
        take(1),
      ),
    )),
  );

И мой тест похож:

test('should ignore the ajax call response when INIT_VIEWS_CANCEL action is fired', (done) => {
    const action$ = ActionsObservable.of({ type: 'INIT_VIEWS' }, { type: 'INIT_VIEWS_CANCEL' });
    const ajaxGet = () => timer(3000);

   initViewsEpic(action$, state$, { ajaxGet })
      .pipe(toArray()).subscribe((actions) => {
        expect(actions).toEqual([
          {
            type: 'TASK_IN_PROGRESS',
            payload: { id: 'INIT_VIEWS' },
          },
          {
            type: 'TASK_COMPLETED',
            payload: { id: 'INIT_VIEWS' },
          },
        ]);
        done();
      });
  });

Я полагаю, что поскольку действие INIT_VIEWS_CANCEL следует за действием INIT_VIEWS синхронно, оно должно "выиграть" ajaxGet и не должно быть никаких initViewsFulFilled.Но результат этого теста всегда возвращает initViewsFulFilled в качестве второго выходного действия моего эпоса (я использую шутку для тестирования эпоса).

Что-то я не так сделал в своем тесте?Если так, как я могу правильно проверить это состояние гонки в наблюдаемом реду эпосе?

1 Ответ

0 голосов
/ 24 марта 2019

Я скажу, что собираюсь дать предложение протестировать наблюдаемые эпосы эпопеи (именно это я и сделал) - используйте TestScheduler в rxjs/testing.Так что нам не нужно почесывать голову, касаясь асциновых вещей других тестовых фреймворков

Надеюсь, это может помочь кому-то, кто имеет ту же проблему, что и я.

...