【问题标题】:How to unit test withLatestFrom in ngrx effects如何在ngrx效果中使用LatestFrom进行单元测试
【发布时间】:2019-06-23 22:40:09
【问题描述】:

我的效果是从 params 获取最新信息并将其传递到一个排气映射,然后调用一个服务。

@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 模拟做什么,我都会返回“您在预期流的位置提供了‘未定义’。”

感谢任何帮助。我真的希望我在弹珠上遗漏了一些东西。

【问题讨论】:

  • 你找到答案了吗?我遇到了完全相同的问题
  • 不。只是让它未经测试。

标签: angular ngrx jasmine-marbles


【解决方案1】:

也许,这是迟到的答案。我遇到了同样的问题。

我不知道确切的原因。在我看来,当 MockStore 和 effect 同时使用时,getRouterState 没有被初始化。在构造函数中初始化 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) => {
.....
);

【讨论】:

    【解决方案2】:

    这有点晚了,但我遇到了类似的问题。我相信您必须使用正确的路由器数据初始化存储。 非常感谢this excellent youtube video by @brian_love 和他的github repo

    注意事项:

    • 我正在使用 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)
          })
        })
    
      })
      
      });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-26
      • 2023-03-13
      • 2019-04-20
      • 2018-10-05
      • 2019-01-14
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      相关资源
      最近更新 更多