NgRx Testing - проверьте порядок отправленных действий - PullRequest
1 голос
/ 05 мая 2020

Я издеваюсь над своим хранилищем NgRx при запуске модульных тестов и создании шпиона Jasmine для функции store.dispatch () .
С этим я, конечно, могу проверить, что:
а. специальное действие c было отправлено через store.dispatch () и
b. количество вызовов имитируемой функции store.dispatch ().

Это видно в следующем фрагменте:

let storeMock;
beforeEach(() => {
  storeMock = {
    dispatch: jasmine.createSpy('dispatch')
  };

  TestBed.configureTestingModule({
    imports: [],
    declarations: [HeaderComponent],
    providers: [
      { provide: Store, useValue: storeMock }
    ]
  });
  TestBed.compileComponents();
});

it(`should dispatch "Loading" and "StoreRecipes" actions when button is clicked`,
      async(() => {
        const fixture = TestBed.createComponent(HeaderComponent);
        fixture.detectChanges();
        const debugElement = queryToGetButton();
        debugElement.nativeElement.click();

        // this works as expected, tests are passing
        expect(storeMock.dispatch).toHaveBeenCalledTimes(2);
        expect(storeMock.dispatch).toHaveBeenCalledWith(
          new RecipeActions.Loading()
        );
        expect(storeMock.dispatch).toHaveBeenCalledWith(
          new RecipeActions.FetchRecipes()
        );
      })
 );

Мне интересно, однако, есть ли способ проверить порядок, в котором отправляются действия?

Выше приведен простой пример модульного теста, но, если запускать интеграционное тестирование позже, я полагаю, было бы полезно иметь способ проверьте порядок, в котором были отправлены различные действия.

Я пробовал напрямую получить доступ к списку вызовов в макете отправки (как это можно сделать в Jest), но я предполагаю, что это не поддерживается в Jasmine ( не получал никаких предложений intellisense при вызове .something в storeMock.dispatch в следующей строке)

expect(storeMock.dispatch.calls).toEqual([
  [new RecipeActions.Loading()], // First call
  [new RecipeActions.FetchRecipes()]  // Second call
]);

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

Можем ли мы проверить порядок отправки вызовов в NgRx с помощью Jasmine?

Любые идеи были бы очень признательны г.

1 Ответ

2 голосов
/ 06 мая 2020

Попробуйте использовать calls.all(). https://daveceddia.com/jasmine-2-spy-cheat-sheet/

it(`should dispatch "Loading" and "StoreRecipes" actions when button is clicked`,
      async(() => {
        const fixture = TestBed.createComponent(HeaderComponent);
        fixture.detectChanges();
        const debugElement = queryToGetButton();
        debugElement.nativeElement.click();

        // this works as expected, tests are passing
        expect(storeMock.dispatch).toHaveBeenCalledTimes(2);
        expect(storeMock.dispatch).toHaveBeenCalledWith(
          new RecipeActions.Loading()
        );
        expect(storeMock.dispatch).toHaveBeenCalledWith(
          new RecipeActions.FetchRecipes()
        );
        // new code
        const allCalls = storeMock.dispatch.calls.all();
        console.log(allCalls);
        const firstCall = allCalls[0].args;
        const secondCall = allCalls[1].args;
        expect(firstCall).toEqual([new RecipeActions.Loading()]);
        expect(secondCall).toEqual([new RecipeActions.FetchRecipes()]); 
      })
 );

Альтернативный способ с использованием callFake:

it(`should dispatch "Loading" and "StoreRecipes" actions when button is clicked`,
      async(() => {
        const fixture = TestBed.createComponent(HeaderComponent);
        fixture.detectChanges();
        const debugElement = queryToGetButton();
        // new code
        let dispatchCount = 0;
        storeMock.dispatch.and.callFake(action => {
          dispatchCount++;
          if (dispatchCount === 1) {
            console.log('first dispatch', action);
            expect(action).toEqual(new RecipeActions.Loading());
          } else {
            console.log('2nd dispatch', action);
            expect(action).toEqual(new RecipeActions.FetchRecipes());
          }
        });
        debugElement.nativeElement.click();

        // this works as expected, tests are passing
        expect(storeMock.dispatch).toHaveBeenCalledTimes(2);
        expect(storeMock.dispatch).toHaveBeenCalledWith(
          new RecipeActions.Loading()
        );
        expect(storeMock.dispatch).toHaveBeenCalledWith(
          new RecipeActions.FetchRecipes()
        );
      })
 );
...