【发布时间】:2019-02-25 17:19:41
【问题描述】:
我想找到一种方法来测试订阅和主题上的取消订阅函数调用。
我想出了一些可能的解决方案,但每一种都有利有弊。请记住,我不想为了测试目的而更改变量的访问修饰符。
- 通过反射访问组件的私有变量。
在这种情况下,我有一个存储订阅的私有类变量:
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。
- 我可以测试右边调用了unsubscribe方法 订阅。
缺点:
- 我只能通过反射访问 mySubscription,如果可能,我希望避免这种情况。
- 我为订阅创建了一个变量,就像在选项 1 中一样。但是我没有通过反射来访问该变量,我只是检查了取消订阅方法是否被调用,而不知道源。
component.ts: 与选项 1 中的相同
component.spec.ts:
spyOn(Subscription.prototype, 'unsubscribe');
component.ngOnDestroy();
expect(Subscription.prototype.unsubscribe).toHaveBeenCalledTimes(1);
优点:
- 我可以测试是否调用了取消订阅方法
缺点:
- 我无法测试调用的取消订阅方法的来源。
- 我实现了一个辅助函数,它在传递的订阅参数上调用取消订阅方法。
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);
优点:
- 我可以测试是否调用了辅助函数
缺点:
- 我无法测试是否在特定订阅上调用了取消订阅函数。
你们有什么建议?如何在单元测试中测试清理?
【问题讨论】:
-
为什么要测试
unsubscribe?这是 rxjs 的一部分,我认为您可以放心地假设它有效 -
我认为 PO 只是想确保
unsubscribe被调用。 -
我想测试组件清理而不是取消订阅的行为。如果我想测试该行为,那么我将检查作为取消订阅调用来源的订阅是否不再处于活动状态。但同样,我想测试该组件是否在每次订阅时调用取消订阅。
标签: angular unit-testing rxjs observable subscription