expectObservable may silently cause a subscription / memory leak
Open
@cartant is already working on this.
Since Mar 14, 2021.
- Dominant language
- TypeScript
- Stars
- 31.7k
- Forks
- 3k
- PR merge metrics
- No merged PRs in 30d
Description
Bug Report
Current Behavior
The TestScheduler:expectObservable internally subscribes to an observable, but the subscription may never be unsubscribed. This causes subscription/memory/state leaks in unit tests that are difficult to detect.
Reproduction
expectObservable(hot('-x-|')).toBe('-x-|'); // good
expectObservable(hot('-x-'), '1s !').toBe('-x-'); // good
expectObservable(hot('-x-')).toBe('-x-'); // leak
expectObservable(cold('-x-')).toBe('-x-'); // leak
expectObservable(NEVER).toBe(''); // leak
Expected behavior
All such subscriptions should be unsubscribed after completion of a test run.
Environment
- Runtime: [e.g. Node Any, Chrome Any]
- RxJS version: 6.5.4
Possible Solution
There are several options for how the issue can be fixed:
TestSchedulershould silently unsubscribe from the observables after completion of the run.TestSchedulershould report a test failure if there are any observable still subscribed after completion of the run.- Add a new helper so a consumer can catch when the run is completed:
const source = helpers.hot('-x-').pipe(takeUntil(helpers.testEnd));
// const source = helpers.takeUntilTestEnd(helpers.hot('-x-'));
helpers.expectObservable(source).toBe('-x-');
Additional context/Screenshots
The possibility of leaks is mentioned at the page https://rxjs.dev/guide/testing/marble-testing#subscription-marbles.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.