Unit testing component with debounceTime rxjs operator is way too hard
See original GitHub issueI’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[x] Feature request
[x] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:
it('should autocomplete schools', fakeAsync(() => {
spectator.click('eb-select2');
spectator.typeInElement('ba', 'input.eb-filter');
// Wait for the debounceTime(500)
tick(500);
spectator.fixture.whenStable().then(() => {
spectator.detectChanges();
const schools = spectator
.queryAll('.eb-select-dropdown .vo-name')
.map(elm => elm.textContent);
expect(schools).toEqual(['Bar', 'Baz']);
});
}));
That code (uses the spectator library, but that just wraps the TestBed API) is required to test a component that has an autocomplete feature that uses debounceTime(500)
ngOnInit() {
this.schools = this.schoolFilter.pipe(
distinctUntilChanged(),
debounceTime(500),
startWith(''),
switchMap(term => {
// etc.
})
);
Testing code that uses the debounceTime operator should not be this difficult. By difficult i mean you have to:
- Wrap the test in
fakeAsync - Advance time using
tick(500) - Then wait until the fixture is table
- Finally
detectChanges
The docs at https://angular.io/guide/testing#fake-async make no mention of having to use whenStable(). In fact it says the opposite: “The fakeAsync function enables a linear coding style by running the test body in a special fakeAsync test zone. The test body appears to be synchronous. There is no nested syntax (like a Promise.then()) to disrupt the flow of control.”
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:27 (6 by maintainers)
Top Results From Across the Web
How to unit test rxjs debounceTime logic (Angular)?
it('Should get suggestions if search term is longer than 2 characters', (done) => { const searchTerm = '123test'; const stringObservable = new ...
Read more >A quick guide to Testing React hooks that use RxJS
React hooks supercharge your functional components in many ways. ... to mouse click and delay the click with RxJs's debounceTime operator.
Read more >Chapter 9. Toward testable, reactive programs - RxJS in Action
js is a full-fledged JavaScript testing framework built for both the browser and Node.js. It runs all of your unit tests serially and...
Read more >How I Write Marble Tests For RxJS Observables In Angular
Unfortunately, testing observables is hard, and to be honest, I often need more time to write unit tests for my streams than to...
Read more >Angular: Testing async stuff in the fakedAsync zone VS ...
Since Angular makes heavy use of RxJs what relies on native timing ... under the hood because it helps to write effective unit...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@jpzwarte as very well explained here: https://stackoverflow.com/a/41658320/1042989, you shouldn’t mix
fakeAsyncwithfixture.whenStable.To get your example working, it should be enough to have a
tickgreater than thedebounceTime(ie: if you’re debouncing for 500ms try withtick(600)) and just remove thefixture.whenStablewrapping.This would make unit testing much more easy and readable.
On my case i have debounce time value on an app
configurationinjected to main module set to 500.When i run tests i have a
mockConfigurationclass that has just debounce time value to 0. So no more values on many services and a simple way to control it on tests.