小编Bal*_*ács的帖子

如何在角度单位测试取消订阅功能

我想找到一种方法来测试订阅和主题上的取消订阅功能调用.

我想出了一些可能的解决方案,但每一个都有利有弊.请记住,我不想为了测试目的而改变变量的访问修饰符.

  1. 使用反射访问组件的私有变量.

在这种情况下,我有一个私有类变量存储订阅:

component.ts:

private mySubscription: Subscription;
//...
ngOnInit(): void {
    this.mySubscription = this.store
        .select(mySelector)
        .subscribe((value: any) => console.log(value));
}

ngOnDestroy(): void {
    this.mySubscription.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)

component.spec.ts:

spyOn(component['mySubscription'], 'unsubscribe');
component.ngOnDestroy();
expect(component['mySubscription'].unsubscribe).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)

优点:

  • 我可以联系到我的订阅.
  • 我可以测试是否在正确的订阅上调用了取消订阅方法.

缺点:

  • 我只能通过反射达到mySubscription,如果可能的话我想避免.

  1. 我为订阅创建了一个变量,就像在选项1中一样.但是我没有使用反射来访问变量,而是在不知道源的情况下检查是否调用了unsubscribe方法.

component.ts:与选项1相同


component.spec.ts:

spyOn(Subscription.prototype, 'unsubscribe');
component.ngOnDestroy();
expect(Subscription.prototype.unsubscribe).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)

优点:

  • 我可以测试是否调用了取消订阅方法

缺点:

  • 我无法测试调用的取消订阅方法的来源.

  1. 我实现了一个辅助函数,它对传递的订阅参数调用unsubscribe方法.

subscription.helper.ts:

export class SubscriptionHelper {

    static unsubscribeAll(...subscriptions: Subscription[]) {
        subscriptions.forEach((subscription: Subscription) => {
                subscription.unsubscribe();
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

component.ts:与选项1中的相同,但ngOnDestroy是不同的:

ngOnDestroy(): void {
    SubscriptionHelper.unsubscribeAll(this.mySubscription);
}
Run Code Online (Sandbox Code Playgroud)

component.spec.ts:

spyOn(SubscriptionHelper, 'unsubscribeAll');
component.ngOnDestroy();
expect(SubscriptionHelper.unsubscribeAll).toHaveBeenCalledTimes(1);
Run Code Online (Sandbox Code Playgroud)

优点:

  • 我可以测试调用辅助函数 …

unit-testing subscription observable rxjs angular

9
推荐指数
3
解决办法
4219
查看次数

避免在RxJs 6中嵌套subcribe()调用

有时,我需要以前可观察到的值,并运行另一个依赖于该值的函数,依此类推。它进行嵌套的subcribe()调用,然后代码非常难看且难以管理。我这里有一个例子:

getObservableData().subcribe(next=>
    let dialogRef=this.dialog.open(EvalListComponent, {data: next})
    dialogRef.afterClosed().subscribe(next=>{
        let k=dialogRef.componentInstance.getAnotherObservableData()
            .subcribe( next=> doSomthing(next))
}))
Run Code Online (Sandbox Code Playgroud)

什么样的解决方案可以遇到这种情况。我需要一些扁平的结构。我知道有一个管道函数,可以与rxjs运算符一起使用。但是如何实现呢?

observable typescript angular rxjs6

3
推荐指数
1
解决办法
811
查看次数