NGRX - проблема с тестированием эффектов, которые преобразуют обещания в наблюдаемые с жасминовыми шариками - PullRequest
0 голосов
/ 09 июня 2019

У меня есть рабочее пространство nrwl / nx с библиотекой под названием missions-shared Эта библиотека имеет состояние объекта под ключом missions У меня также есть бэкэнд-служба, которая называется BackendServiceClient. Этот сервер возвращает обещания (из-за генерации кода)

Моя проблема в том, что бэкэнд возвращает обещания, а жасминовый шарик не может распознать, что:

Я пытаюсь издеваться над бэкэндом. Я использую тестовый провайдер для этого


let backend = {
  get: () => Promise.resolve({items: []})
}

TestBed.configureTestingModule({
...
providers : [{
  provide: BackendServiceClient, useValue: backend
}]
...

Это эффект миссии:


@Injectable()
export class MissionsEffects {
  @Effect() loadMissions$ = this.dataPersistence.fetch(
    MissionsActionTypes.LoadMissions,
    {
      run: (action: LoadMissions, state: MissionsPartialState) => {
        return from(this.backend.get(new GetMissions())).pipe(
          map(r => new MissionsLoaded(r.items))
        );
      },

      onError: (action: LoadMissions, error) => {
        console.error('Error', error);
        return new MissionsLoadError(error);
      }
    }
  );

  constructor(
    private dataPersistence: DataPersistence<MissionsPartialState>,
    private backend: BackendClientService
  ) {}
}

Затем я пытаюсь проверить эти @Effect, используя жасминовые шарики

   actions = hot('-a-|', { a: new LoadMissions() });
   expect(effects.loadMissions$).toBeObservable(
     hot('-a-|', { a: new MissionsLoaded([]) })
   );

Но я получаю эту ошибку в тестах:

  ● MissionsEffects › loadMissions$ › should work

    expect(received).toEqual(expected) // deep equality

    - Expected
    + Received

    - Array [
    -   Object {
    -     "frame": 10,
    -     "notification": Notification {
    -       "error": undefined,
    -       "hasValue": true,
    -       "kind": "N",
    -       "value": MissionsLoaded {
    -         "payload": Array [],
    -         "type": "[Missions] Missions Loaded",
    -       },
    -     },
    -   },
    -   Object {
    -     "frame": 30,
    -     "notification": Notification {
    -       "error": undefined,
    -       "hasValue": false,
    -       "kind": "C",
    -       "value": undefined,
    -     },
    -   },
    - ]
    + Array []

Кажется, потому что я издеваюсь над бэкэндом, используя Promise (как и должно быть), он не распознает возвращаемую Observable.

Если я поменяю макет на:

let backend = {
  get: () => of({items: []})
}

Тогда тест пройден успешно.

Это тест:


describe('MissionsEffects', () => {
  let actions: Observable<any>;
  let effects: MissionsEffects;
  let backend = {
    get: () => of({items: []})
  }

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        NxModule.forRoot(),
        StoreModule.forRoot({}),
        EffectsModule.forRoot([]),
        RouterModule.forRoot([])
      ],
      providers: [
        MissionsEffects,
        DataPersistence,
        provideMockActions(() => actions),
        { provide: APP_BASE_HREF, useValue: '/' },
        { provide: BackendClientService, useValue: backend }
      ]
    });

    effects = TestBed.get(MissionsEffects);
  });

  describe('loadMissions$', () => {
    it('should work', () => {
      actions = hot('-a-|', { a: new LoadMissions() });
      expect(effects.loadMissions$).toBeObservable(
        hot('-a-|', { a: new MissionsLoaded([]) })
      );
    });
  });
});


Я могу подтвердить, что проблема не в использовании @ nrwl / DataPersistence, так как следующий @Effect вызывает ту же ошибку:


@Injectable()
export class MissionsEffects {

  @Effect() loadMissions$ = this.actions$
    .pipe(
      ofType(MissionsActionTypes.LoadMissions),
      switchMap(loadMission => {
        return from(this.backend.get(new GetMissions())
          .then(r => new MissionsLoaded(r.items))
          .catch(e => new MissionsLoadError(e)))
      })
  )

  constructor(
    private actions$: Actions,
    private backend: BackendClientService
  ) {}
}

Может кто-нибудь помочь мне точно понять, в чем здесь проблема? Почему я не могу использовать осмеянные обещания, чтобы проверить это?

1 Ответ

0 голосов
/ 11 июня 2019

Вы можете попробовать обернуть ваш тест в async(), чтобы убедиться, что все асинхронные вызовы завершены.Хотя resolve является синхронным, from добавит .then и все еще будет ждать его разрешения в качестве микрозадачи.Обертывание вашей it функции с async или fakeAsync исправит это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...