I would like to find a way to test unsubscribe function calls on Subscriptions and Subjects.
I came up with a few possible solutions, but every one of these have pros and cons. Please keep in mind that I do not want to alter the access modifier of a variable for testing purposes.
- Accessing private variable of component with reflection.
In that case I have a private class variable which stores a subscription:
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);
pros:
- I can reach mySubscription.
- I can test that the unsubscribe method was invoked on the right subscription.
cons:
- I can reach mySubscription only with reflection, what I would like to avoid if possible.
- I create a variable for subscription just like in option 1., but instead of reaching the variable with reflection I simply check that the unsubscribe method was invoked, without knowing the source.
component.ts: same as in option 1
component.spec.ts:
spyOn(Subscription.prototype, 'unsubscribe');
component.ngOnDestroy();
expect(Subscription.prototype.unsubscribe).toHaveBeenCalledTimes(1);
pros:
- I can test that the unsubscribe method was called
cons:
- I can not test the source of the invoked unsubscribe method.
- I implemented a helper function which invokes unsubscribe method on the passed parameters which are subscriptions.
subscription.helper.ts:
export class SubscriptionHelper {
static unsubscribeAll(...subscriptions: Subscription[]) {
subscriptions.forEach((subscription: Subscription) => {
subscription.unsubscribe();
});
}
}
component.ts: same as in option 1, but ngOnDestroy is different:
ngOnDestroy(): void {
SubscriptionHelper.unsubscribeAll(this.mySubscription);
}
component.spec.ts:
spyOn(SubscriptionHelper, 'unsubscribeAll');
component.ngOnDestroy();
expect(SubscriptionHelper.unsubscribeAll).toHaveBeenCalledTimes(1);
pros:
- I can test that the helper function was called
cons:
- I can not test that the unsubscribe function was called on a specific subscription.
What do you guys suggest? How do you test the cleanup in unit test?
unsubscribe
? this is a piece of rxjs and I think you can safely assume it works – Hugohugonunsubscribe
is getting called. – Escutcheon