【问题标题】:How to test a RxJs callback in jasmine如何在 jasmine 中测试 RxJs 回调
【发布时间】:2018-02-22 14:27:28
【问题描述】:

我在我的组件中使用 NgbTypeAhead,其中回调必须是 (text: Observable<string>) => Observable<any[]> 。现在,我想测试搜索的副作用,但我正在努力用 jasmine 编写该测试。

有人可以帮忙吗?提前致谢。

component.ts

search = (text$: Observable<string>) =>
        text$
            .debounceTime(200)
            .distinctUntilChanged()
            .do((term: string) => {
                console.log("do 1", term)
                this.isSearching = true && term !== "";
                this.cd.markForCheck();
            })
            .map(term => {
                console.log("map", term)
                return term === ""
                    ? this.list
                    : this.filter(term)
            })
            .do(list => {
                console.log("do 2", list)
                this.searchResultsCount = list.length;
                this.cd.markForCheck();
            });

component.html

<input #initiativeSearch type="text" id="initiativeSearch" 
    [ngbTypeahead]="search"/>

component.spec.ts

 it("should update searching flags", () => {
       // how do I test this ? here is what I tried
        let spyObj = jasmine.createSpyObj<Observable<string>>("text$", ["debounceTime", "distinctUntilChanged", "do", "map"]);

        spyObj.debounceTime.and.returnValue(spyObj)
        spyObj.distinctUntilChanged.and.returnValue(spyObj)
        spyObj.do.and.returnValues(Observable.of("blabla"), Observable.of([]))
        spyObj.map.and.returnValue(Observable.of([]))
        component.searchInitiatives(spyObj);

        expect(spyObj.debounceTime).toHaveBeenCalledWith(200);
        expect(spyObj.distinctUntilChanged).toHaveBeenCalledTimes(1);
        expect(spyObj.do).toHaveBeenCalledTimes(2);
    });

这会在控制台中记录spy text$.do to have been called 2 times. It was called 1 times.,并且不会显示任何console.log

【问题讨论】:

  • 我不这么认为,我的函数是一个回调,它本身不返回任何值,

标签: angular jasmine rxjs ng-bootstrap


【解决方案1】:

听起来您的测试方向错误。如果您进行单元测试,您只需一次测试一个组件即可。

您只需要直接测试您的搜索组件。你可以这样做:

let observableSpy = {
  debounceTime: observableSpy,
  distinctUntilChanged: observableSpy,
  // ... repeat for all properties
};
let spyObj = jasmine.createSpyObj(observableSpy);

然后将spyObj 传递给您的搜索功能:

search(spyObj)

最后,运行一些断言:

expect(spyObj.debounceTime).toHaveBeenCalledWith(...);
// ... test all calls.

这样做更像是一个单元测试。

【讨论】:

  • 感谢您的提示,我尝试了您的建议,但仍然无效(更新后的帖子)。我认为现在的问题是要正确测试Observable 方法的链接,我必须使用它们正确的返回值来模拟这些方法,这仍然对我不起作用。我不明白我应该如何测试茉莉花中的链接,还有其他想法吗?
  • 为了存根链接方法,您总是需要返回 spyObj。我看到您在上面的示例中没有这样做。那会是你的问题吗?而不是spyObj.do.and.returnValues(Observable.of("blabla"), Observable.of([])),而是spyObj.do.and.returnValue(spyObj)
  • 谢谢。所以,这确实有效,这样我可以确保我的链条是正确的。 ...但我还想检查domap 是否调用了正确的回调,知道该怎么做吗?
【解决方案2】:

您可以测试此功能,但您需要在 Angular 的“主区域”之外使用 fakeAsync 装饰器对其进行测试。

也就是说,我强烈建议不要这样做。对我来说,您似乎正在尝试测试不在您的单元测试范围内的 ReactiveX 运算符。使用这些库时,应该假设该库有自己的单元测试。您可能想要测试是否传入了以毫秒为单位的正确值,但您实际上不需要或不想测试 debounceTime 运算符。

请让我们知道这是否有意义,如果没有,我们可以找到其他更好的方法来为您的断言找到覆盖范围,但是我不建议您将精力集中在测试 RXJS 框架上。

【讨论】:

  • 我不想测试框架。只需确保以正确的顺序调用 RxJs 函数,并确保 mapdo 调用正确的依赖项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2019-09-13
相关资源
最近更新 更多