【问题标题】:How do you unit test ngrx effects with Angular 6 and without jasmine-marbles?你如何在没有 jasmine-marbles 的情况下使用 Angular 6 对 ngrx 效果进行单元测试?
【发布时间】:2019-01-14 22:55:28
【问题描述】:

我正在尝试为我的效果编写一些单元测试,但似乎测试没有到达我拥有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 和最新的 ngrxRxJS 6

谢谢!

【问题讨论】:

  • 尝试改变tick内的时间,给它更多然后再试一次

标签: angular jasmine angular6 ngrx-effects rxjs6


【解决方案1】:

这行得通吗?

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

【讨论】:

  • 这段代码确实通过了测试,但是我在toEqual() 函数中输入了一些垃圾数据,它仍然通过了测试。我认为问题在于subscribe 中的代码永远不会触发,或者我的效果设置有问题。
【解决方案2】:

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

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】:

    您可以使用来自“rxjs”的主题来模拟来自“@ngrx/effects”的操作

    const actions = new Subject();
    

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

    { provide: Actions, useValue: actions }
    

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

    【讨论】:

      猜你喜欢
      • 2018-01-04
      • 2023-03-13
      • 2018-05-15
      • 2019-02-06
      • 2019-10-24
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多