Simplify usage with factory function and internal subscription handling
See original GitHub issueHey Shai!
Thanks for this! It makes basic observable testing a lot easier! I replaced almost all marble tests in my current project using observer spies, and I do love them. When you don’t have to make use of the complexity which comes with marble testing, observer spies are a real improvement in terms of clarity and readability. However, I found the few lines to use them still a bit too implementation heavy 😉 I know this is a matter of taste, so please consider this more like a feature proposal than a feature request.
Is your feature request related to a problem? Please describe. Letting test authors handle subscriptions on their own leads to a bit too much boilerplate code.
Describe the solution you’d like I ended up using observer spies like this:
const fakeObservable = of('first', 'second', 'third');
const spy = spyOnObservable(fakeObservable);
// if the observable under test will not complete
// or we just want the spy to stop listening
// this will internally unsubscribe
spy.stop();
// simplified shorthand usage
expect(spyOnObservable(fakeObservable).getFirstValue()).toBe('first');
For that to work, I extended the ObserverSpy Class to handle the subscription itself and added a stop method to give test authors the possibility to clear subscriptions:
class StoppableObserverSpy<T> extends ObserverSpy<T> {
private observationStopped = new AsyncSubject<never>();
constructor(observableUnderTest: Observable<T>) {
super();
observableUnderTest
.pipe(
finalize(() => this.stop()),
takeUntil(this.observationStopped)
)
.subscribe(this);
}
public stop(): void {
if (!this.observationStopped.isStopped) {
this.observationStopped.complete();
this.observationStopped.unsubscribe();
}
}
}
Additionally I use this simple factory function:
function spyOnObservable<T>(observableUnderTest: Observable<T>) {
return new StoppableObserverSpy<T>(observableUnderTest);
}
Describe alternatives you’ve considered Maybe the usage of observer spies could be simplified even more by creating custom jasmine/jest matchers, but I have no experience there.
Additional context I guess the proposed modifications could be applied to this library without introducing breaking changes. If you think that these changes would be useful, I’d love to create a PR for discussing implementation details.
Cheers, kat
Issue Analytics
- State:
- Created 3 years ago
- Reactions:2
- Comments:7 (7 by maintainers)
Top GitHub Comments
Sure thing! I get on to it. 😊
Thanks a lot @katharinakoal !
@edbzn I agree, having specific matchers means we need to support different frameworks, so it’s better to minimize the peer dependencies.
This could be an extension if it will be useful.
Thanks for the feedback!