在 RxJs 和 Angular 中测试可观察的"下一个"回调



我试图用RxJs Observables在Angular中做一个非常简单的测试,但我做得不够。这就是我基本上要测试的:

// We're inside some Angular component here...
let testMe = 0;
function somethingOrOther(): void {
this.someService.methodReturningObservable()
.subscribe(
(nextValue: number): void => {
testMe += nextValue;
}
) 
}

methodReturningObservable后面的可观测值发出值时,我如何测试testMe是否正确更新?

我尝试过这个:

it(`works 'cuz I want it to`, fakeAsync(() => {
spyOn(this.someService, 'methodReturningObservable').and.returnValue(cold('a', {a: 10}));
tick();
expect(component.testMe).toBe(10);
}));

因此,tick()在这里似乎没有任何作用。没有什么能让我的cold值在我的间谍身上发布。

我尝试了getTestScheduler.flush(),如中所示https://netbasal.com/testing-observables-in-angular-a2dbbfaf5329大理石部分下方。

我可以用这样的弹珠在可观测的物体上发射一个值吗?这在AngularJS中非常容易,只需触发一个摘要,但我似乎无法让Anguar让我在下一次回调中进行观察。

我制作了一个简单的Stacklitz,向您展示如何测试您描述的简单组件方法。

以下是Stacklitz的规格:

it(`works with "of" 'cuz I want it to`, () => {
spyOn(someService, 'methodReturningObservable').and.returnValue(of(10));
component.somethingOrOther();
expect(component.testMe).toBe(10);
});

我对你的代码做了一些更改:

  • 我不得不对您的组件方法进行一些小的更改,以使其正常工作。Stacklitz中的详细信息
  • cold()函数来自大理石测试库,但对于这样一个简单的函数来说,这太过分了。rxjs提供了ofObservable创建方法,该方法可以创建一个可以订阅的冷同步Observable(但如果您真的想以这种方式进行测试,请参阅下文(
  • 由于上面的规范使用了同步可观测,因此不需要fakeAsync(),因为它会立即完成
  • 需要显式调用要测试的被测方法,如上所述,使用component.somethingOrOther()

正如您在Stacklitz中看到的,此测试通过得很好。

现在,如果你想使用大理石测试,即使是在这个简单的情况下,我在Stacklitz中为此设置了另一个规范。如下所示:

it(`works with "cold" 'cuz I want it to`, () => {
spyOn(someService, 'methodReturningObservable').and.returnValue(cold('a', { a: 10 }));
component.somethingOrOther();
getTestScheduler().flush(); // flush the observables
expect(component.testMe).toBe(10);
});
  • 注意需要调用组件函数
  • getTestScheduler的刷新也需要完成

这两项测试现在都通过了Stacklitz。

Angular中大理石测试的官方文档在这里。

我希望这能有所帮助。

最新更新