Угловой шпион ngrx / store в области Promise - PullRequest
0 голосов
/ 28 июня 2019

Я пишу тест с Angular TestBed со следующей настройкой:

let cacheService: CacheService;
let store: Store<PsaAppState>;
let service: ConfigService;

beforeEach(() => {
  TestBed.configureTestingModule({
    providers: [
      ConfigService,
      { provide: TranslateService, useValue: getMock(TranslateService) },
      { provide: CacheService, useValue: getMock(CacheService) },
      { provide: Store, useValue: getMock(Store) }
    ]
  });
  const injector: TestBed = getTestBed();
  service = injector.get(ConfigService);
  cacheService = injector.get(CacheService);
  store = injector.get(Store);
});

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

it('Should dispatch FetchFeatureConfigAction when promise is rejected', () => {
    spyOn(store, 'dispatch').and.stub();
    spyOn(cacheService, 'getRawItem').and.returnValue(Promise.reject('error'));

    service.getFeatureConfig();
    expect(store.dispatch).toHaveBeenCalledTimes(1);
    expect(store.dispatch).toHaveBeenCalledWith(new FetchFeatureConfigAction());
});

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

getFeatureConfig() {
    console.log('###Service called!!!');
    this.cacheService.getRawItem('APP_STATE_NAME').then(
      (appState: PsaAppState) => {
        console.log('###Resolve with ', appState);
        !isNil(appState.featureConfigState.featureConfig)
          ? this.store$.dispatch(new FetchFeatureConfigSuccessAction(appState.featureConfigState.featureConfig))
          : this.store$.dispatch(new FetchFeatureConfigAction());
      },
      err => {
        console.log('###Rejected with ', err);
        this.store$.dispatch(new FetchFeatureConfigAction());
      }
    );
  }

Я могу видеть журналы в отклоненном обратном вызове (также в разрешенном для других тестов), но ожидания терпят неудачу без взаимодействия.Я предполагаю, что проблема this.store$.dispatch в области действия Promis является проблемой.

Верно ли это предположение и как я могу выполнить этот тест?

1 Ответ

0 голосов
/ 03 июля 2019

Основная причина заключается в том, что Обещание еще не разрешено, когда вызывается служба и выполняется console.log. Это связано с тем, что Javascript Event Loop обрабатывает асинхронные запросы.

Исправление ошибки:

it('Should dispatch FetchFeatureConfigAction when promise is rejected', () => {
    spyOn(store, 'dispatch').and.stub();
    const expectedPromise = Promise.reject('error');
    spyOn(cacheService, 'getRawItem').and.returnValue(expectedPromise);

    service.determineFeatureConfig();
    expectedPromise.catch(() => {
      expect(store.dispatch).toHaveBeenCalledTimes(1);
      expect(store.dispatch).toHaveBeenCalledWith(new FetchFeatureConfigAction());
    });
});

Я извлек Обещание в переменную, а затем внутри catch ожидания работают нормально.

Для хороших случаев решение может быть с синтаксисом затем или async / await . Пример для последнего будет выглядеть так:

it('Should dispatch FetchFeatureConfigAction when promise is resolved', async () => {
    spyOn(store, 'dispatch').and.stub();
    const expectedPromise = Promise.resolve('success');
    spyOn(cacheService, 'getRawItem').and.returnValue(expectedPromise);

    service.determineFeatureConfig();
    await expectedPromise;
    expect(store.dispatch).toHaveBeenCalledTimes(1);
    expect(store.dispatch).toHaveBeenCalledWith(new FetchFeatureConfigAction());
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...