Как выполнить модульное тестирование с помощью LastFrom в эффектах ngrx

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

@Effect()
loadPlansOnParams$ = this.actions$.pipe(
 ofType(backlogActions.BacklogActionTypes.GET_BOARDS_IN_PARAMS),
 withLatestFrom(this.store.select(fromRoot.getRouterState), (action, router) => {
   const {
     state: {
       queryParams: { boards },
     },
   } = router;
   return {
     boards,
   };
 }),
 exhaustMap(payload => {
   return this.boardService.getBoardsFromParams(payload.boards).pipe(
     map((res: SignalRResult) => {
       const board = res.item;
       return new backlogActions.GetBoardsSuccess(board);
     }),
     catchError(err => of(new backlogActions.GetBoardsError(err))),
   );
 }),
);

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

Вот мой тест ...

describe('getting boards from the params', () => {
    it('should return an empty array if no params', () => {
      const params = { state: { queryParams: {} } };
      const successfulSignalRResult = { isSuccessful: true, item: [] };
      const action = new backlogActions.GetBoardsInParams();
      const outcome = new backlogActions.GetAvailableBoardsSuccess([]);
      actions.stream = hot('-a', { a: action });
      store.select = jest.fn(() => of(params));
      expected = cold('--b', { b: outcome });
      boardSvc.getBoardsFromParams = jest.fn(() => successfulSignalRResult);
      expect(effects.loadPlansOnParams$).toBeObservable({});
    });
  });

Независимо от того, что я делаю с макетом store.select, я получаю ответ: «Вы указали undefined там, где ожидался поток».

Любая помощь приветствуется. Я очень надеюсь, что мне что-то не хватает по мрамору.


person s.Lawrenz    schedule 30.01.2019    source источник
comment
Вы нашли на это ответ? Я столкнулся с той же проблемой   -  person Jagpreet Singh    schedule 09.01.2020
comment
Неа. Просто оставил это непроверенным.   -  person s.Lawrenz    schedule 10.01.2020


Ответы (2)


Возможно, это поздний ответ. Я столкнулся с такой же проблемой.

Я не знаю точной причины. На мой взгляд, getRouterState не инициализируется, когда MockStore и эффект используются одновременно. Когда loadPlansOnParams $ инициализируется в конструкторе, getRouterState не инициализируется должным образом.

Проще говоря, инициализация getRouterState находится перед loadPlansOnParams $ вот так.

@Effect()

SomeVariableForGetRouterState:Observable<SomeThing> = ..... fromRoot.getRouterState ..... like this.. 

loadPlansOnParams$ = this.actions$.pipe(
ofType(backlogActions.BacklogActionTypes.GET_BOARDS_IN_PARAMS),
withLatestFrom( SomeVariableForGetRouterState, (action, router) => {
.....
);
person Sang B. Han    schedule 21.04.2020

Это немного поздно, но у меня была аналогичная проблема. Я считаю, что вам нужно инициализировать магазин с правильными данными маршрутизатора. Большое спасибо за это отличное видео на YouTube от @brian_love и его репозиторий github

На заметку:

  • Я использую provideMockStore и provideMockActions
  • Я инициализирую TestBed и предоставляю свои фиктивные реализации

Вот мой рабочий пример:

import { cold, hot } from 'jasmine-marbles'
import { provideMockActions } from '@ngrx/effects/testing';
import { MockStore, provideMockStore } from '@ngrx/store/testing';
import { TestBed } from '@angular/core/testing';

import * as fromStore from '.';
import { ApplicationDocument } from 'shared-libs';
import { Actions } from '@ngrx/effects';
import { ApplicationDocumentService } from '../application-document.service';
import { ApplicationDocumentEffects } from './application-document.effects';

describe('ApplicationDocument Store', () => {

  let applicationDocument: ApplicationDocument
  let error: any
  let actions$: Actions
  let service: ApplicationDocumentService
  let effects: ApplicationDocumentEffects
  let store: any
  
  describe('effects', () => {
  // Note: Must initialize store with router state
    const initialState = {
      router: {
        state: { params: { applicationId: 1 } }
      }
    }
    
    beforeEach(async () => {
      TestBed.configureTestingModule({
        providers: [
          ApplicationDocumentEffects,
          provideMockStore({ initialState }), //<-- must provide the initialState to the mockStore
          provideMockActions(() => actions$),
          {
            provide: ApplicationDocumentService,
            useValue: {
              getDocuments: jest.fn()
            }
          }
        ]
      })

      effects = TestBed.inject(ApplicationDocumentEffects)
      service = TestBed.inject(ApplicationDocumentService)
      store = TestBed.inject(MockStore)
    })
    
    
    it('should be created', () => {
      expect(effects).toBeTruthy();
    });
    
    describe('loadDocuments', () => {

      it('should return loadApplicationDocumentsSuccess action, with the documents', () => {
        applicationDocument = {documentId: 1};

        const action = fromStore.loadApplicationDocuments();
        const outcome = fromStore.loadApplicationDocumentsSuccess({ 
          applicationDocuments: [applicationDocument] 
        })
        actions$ = hot('-a', { a: action })

        const response = cold('-a|', { a: [applicationDocument] })
        const expected = cold('--b', { b: outcome })
        service.getDocuments = jest.fn(() => response)

        expect(effects.loadApplicationDocuments$).toBeObservable(expected)
      })
    })

  })
  
  });

person daudihus    schedule 13.02.2021