【问题标题】:How to test multilple subscription in Angular?如何在 Angular 中测试多个订阅?
【发布时间】:2020-06-25 16:55:54
【问题描述】:

在我的 Angular 单元测试中,当我调用主题 myComponent.clearInput$.next() 时,我想检查 myComponent.items$ 是否有 0 个结果。在此之前,我想确保有一些记录。 myComponent.items$ 可以填充为myComponent.nameInput$.next("test")

不幸的是,两个订阅都是在调用两个主题后触发的,所以myComponent.items$ 始终为 0。

it("when control touched then clear input value", done => {

    myComponent.items$.pipe(first()).subscribe(result => {
        expect(result.length).toBe(2); 
        // it's always 0 because of myComponent.clearInput$.next(); from last line
    })
    myComponent.nameInput$.next("test");

// Now should wait after code from above will finish then the rest should be executed after that.

    myComponent.items$.pipe(first()).subscribe(result => {
        expect(result.length).toBe(0);
        done(); // test should be finished here
    })
    myComponent.clearInput$.next();
});

这就是那些主题如何调用 items$

this.items$ = merge(
    this.nameInput$.pipe(
        switchMap((name: string) =>
            iif(() => this._partyType === "PT",
                this.someService.getByName(name),
                this.otherService.getByOtherName(name)
            )
        )
    ),
    this.clearInput$.pipe(
        switchMapTo(of([]))
    )
);

【问题讨论】:

    标签: angular typescript unit-testing jasmine angular-unit-test


    【解决方案1】:

    在我的单元测试中,我很少subscribe。我使用promise 方法,因为这样我可以等待。

    试试这个:

    it("when control touched then clear input value", async done => {
       myComponent.nameInput$.next("test");
       console.log('first await...');
       const result = await myComponent.items$.pipe(take(1)).toPromise();
       console.log('after first await...');
       expect(result.length).toBe(2);
    
       myComponent.clearInput$.next();
       console.log('second await...');
       const newResult = await myComponent.items$.pipe(take(1)).toPromise();
       console.log('after second await...');
       expect(newResult.length).toBe(0);
       done();
    });
    

    我想这就是你想要的。这样我们就可以拥有阻塞代码和更好的断言。

    【讨论】:

    • 我有一个错误:错误:超时 - 异步函数没有在 5000 毫秒内完成(由 jasmine.DEFAULT_TIMEOUT_INTERVAL 设置)
    • 好的,测试卡在Promise 上。确保测试结构良好,组件也结构良好。我加了console.logs,看看哪个after ...日志你没看到,那是从未解决的promise。
    • console.log('after first await...'); 永远不会被触发
    • 这意味着items$ 不会触发。 nameInput$items$ 有什么关系?
    • 我认为这是因为nameInput$ 是一个主题(不是ReplaySubject)所以当我们调用toPromise() 时没有任何缓存值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    相关资源
    最近更新 更多