在RxJ和Angular中测试可观察到的“下一个”回调

时间:2018-12-13 22:02:56

标签: angular rxjs jasmine-marbles rxjs-marbles

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

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

我尝试这样做:

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让我在下一个回调中获得可观察到的结果。

1 个答案:

答案 0 :(得分:3)

我整理了一个简单的Stackblitz,向您展示了如何测试您描述的简单组件方法。

这是Stackblitz的规格:

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

我对您的代码进行的一些更改:

  • 我必须对您的组件方法进行一些小的更改才能使其工作。 Stackblitz中的详细​​信息。
  • cold()函数来自大理石测试库,但是对于这样一个简单的函数而言,这太过分了。 rxjsof种可观察的创建方法,可以创建一个可以订阅的冷同步可观察的方法(但如果您真的想用这种方法进行测试,请参见下文)。
  • 由于上述规范使用了同步可观察对象,因此不需要fakeAsync(),因为它将立即完成。
  • 需要显式调用被测方法以进行测试,上面用行component.somethingOrOther()完成了。

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

现在,如果您即使在这种简单情况下也想使用大理石测试,我会在Stackblitz中为此设置另一个规范。如下:

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的刷新。

这两个测试现在都通过了Stackblitz。

在Angular中进行大理石测试的官方文档为here

我希望这会有所帮助。