如何在Angular 6和不带茉莉花大理石的情况下对ngrx效果进行单元测试?

时间:2018-08-07 19:03:35

标签: angular jasmine angular6 ngrx-effects rxjs6

我正在尝试为自己的效果编写一些单元测试,但似乎测试未达到我拥有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,测试失败。

请注意,我正在将 Angular 6 与最新的ngrx RxJS 6 一起使用。

谢谢!

3 个答案:

答案 0 :(得分:1)

最终,必须使用rxjs中的ReplaySubject。必须在ReplaySubject函数中实例化一个新的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());
    });
});

答案 1 :(得分:0)

这行吗?

effects.loadData$.subscribe(result => {
    data = result;
    expect(data).toEqual(fromData.LoadDataSuccess);
});

答案 2 :(得分:0)

您可以将'@ ngrx / effects'中的操作与'rxjs'中的Subject进行模拟

const actions = new Subject();

然后在测试模块的提供程序中

{ provide: Actions, useValue: actions }

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

相关问题