代码之家  ›  专栏  ›  技术社区  ›  J-man

如何使用Angular 6和jasmine大理石对ngrx效果进行单元测试?

  •  3
  • J-man  · 技术社区  · 7 年前

    我正试图为我的效果编写一些单元测试,但似乎测试没有达到我的目标 expect jasmine-marbles ,我只想用普通的 jasmine

    @Effect
    loadData$: Observable<Action> = this.actions$.pipe(
        ofType(actions.LOAD_DATA),
        switchMap(actions =>
            this.dataService.getData().pipe(
                map(data => new actions.LoadDataSuccess(data)),
                catchError(err => of(new actions.LoadDataFailed(err)))
            )
        )
    );
    

    规格文件

    let effects: fromData.DataEffects;
    let actions: Observable<any>;
    let mockState: fromData.DataState;
    let mockDataService: jasmine.SpyObj<DataService>;
    
    beforeEach((async(() => {
        mockState = { name: 'Test', age: 40 };
        mockDataService = jasmine.createSpyObj({'dataService', getData: of<Data>(mockState)});
        TestBed.configureTestingModule({
            imports: [],
            providers: [
                fromData.DataEffects,
                provideMockActions(() => actions),
                { provide: DataService, useValue: mockDataService }
            ]
        });
        effects = TestBed.get(fromData.DataEffects);
    })));
    
    it('should return new success action after load', fakeAsync(() => {
        let data: any;
        const actions = new ReplaySubject(1);
        actions.next(new fromData.LoadAction());
        effects.loadData$.subscribe(result => {
            data = result;
        });
        tick(100);
        expect(data).toEqual(fromData.LoadDataSuccess);
    }));
    

    测试失败是因为 Expected undefined to equal Function .

    注意:我正在使用 角度6 最新的 ngrx RxJS 6

    谢谢

    3 回复  |  直到 7 年前
        1
  •  1
  •   danday74    7 年前

    effects.loadData$.subscribe(result => {
        data = result;
        expect(data).toEqual(fromData.LoadDataSuccess);
    });
    
        2
  •  1
  •   J-man    7 年前

    最终,我们不得不使用 ReplaySubject 来自rxjs。必须实例化一个新的 actions 中的对象 beforeEach(async(())

    actions = new ReplaySubject(1);
    

    it('should return new success action after load', (done) => {
        actions.next(new fromData.LoadAction());
        const sub = effects.loadData$.subscribe(result => {
            expect(result).toEqual(fromData.LoadDataSuccess(mockState));
            done();
            setTimeout(() => sub.unsubscribe());
        });
    });
    
        3
  •  0
  •   Massimo    7 年前

    您可以使用“rxjs”中的主题模拟“@ngrx/effects”中的动作

    const actions = new Subject();
    

    然后在测试模块的提供者中

    { provide: Actions, useValue: actions }
    

    在单元测试中,当您需要触发某些效果时,订阅您的效果以测试您预期的操作/行为。然后简单地调用actions.next(new TriggerAction())。