我想找到一种方法来测试订阅和主题上的取消订阅功能调用.
我想出了一些可能的解决方案,但每一个都有利有弊.请记住,我不想为了测试目的而改变变量的访问修饰符.
>使用反射访问组件的私有变量.
在这种情况下,我有一个私有类变量存储订阅:
component.ts:
private mySubscription: Subscription; //... ngOnInit(): void { this.mySubscription = this.store .select(mySelector) .subscribe((value: any) => console.log(value)); } ngOnDestroy(): void { this.mySubscription.unsubscribe(); }
component.spec.ts:
spyOn(component['mySubscription'],'unsubscribe'); component.ngOnDestroy(); expect(component['mySubscription'].unsubscribe).toHaveBeenCalledTimes(1);
优点:
>我可以达到我的订阅.
>我可以测试在右侧调用取消订阅方法
订阅.
缺点:
>我只能通过反射达到mySubscription,如果可能的话我想避免.
>我为订阅创建了一个变量,就像在选项1中一样.但是我没有使用反射来访问变量,而是在不知道源的情况下检查是否调用了unsubscribe方法.
component.ts:与选项1相同
component.spec.ts:
spyOn(Subscription.prototype,'unsubscribe'); component.ngOnDestroy(); expect(Subscription.prototype.unsubscribe).toHaveBeenCalledTimes(1);
优点:
缺点:
>我实现了一个辅助函数,它对传递的订阅参数调用unsubscribe方法.
subscription.helper.ts:
export class SubscriptionHelper { static unsubscribeAll(...subscriptions: Subscription[]) { subscriptions.forEach((subscription: Subscription) => { subscription.unsubscribe(); }); } }
component.ts:与选项1中的相同,但ngOnDestroy是不同的:
ngOnDestroy(): void { SubscriptionHelper.unsubscribeAll(this.mySubscription); }
component.spec.ts:
spyOn(SubscriptionHelper,'unsubscribeAll'); component.ngOnDestroy(); expect(SubscriptionHelper.unsubscribeAll).toHaveBeenCalledTimes(1);
优点:
缺点:
你们有什么建议?你如何在单元测试中测试清理?
解决方法
关于你的最后一点
I can not test that the unsubscribe function was called on a specific subscription.
你可以这样做.
// get your subscrption const mySubscription = component['mySubscription']; // use the reference to confirm that it was called on that specific subscription only. expect(SubscriptionHelper.unsubscribeAll).toHaveBeenCalledWith(mySubscription);
现在,当涉及到测试时,它应该只检查/访问/调用公共成员,并测试/期望其影响.
使用javascript的奢侈品,你期待/验证私人成员,即使这样我觉得很好.即使我这样做,我也可能是错的.欢迎富有成效的批评和评论.