Unit testing component with debounceTime rxjs operator is way too hard

See original GitHub issue

I’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:

  1. Wrap the test in fakeAsync
  2. Advance time using tick(500)
  3. Then wait until the fixture is table
  4. 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:closed
  • Created 5 years ago
  • Reactions:9
  • Comments:27 (6 by maintainers)

github_iconTop GitHub Comments

16reactions
fagiacommented, Mar 28, 2019

@jpzwarte as very well explained here: https://stackoverflow.com/a/41658320/1042989, you shouldn’t mix fakeAsync with fixture.whenStable.

To get your example working, it should be enough to have a tick greater than the debounceTime (ie: if you’re debouncing for 500ms try with tick(600)) and just remove the fixture.whenStable wrapping.

This would make unit testing much more easy and readable.

7reactions
meriturvacommented, Aug 13, 2018

On my case i have debounce time value on an app configuration injected to main module set to 500.

When i run tests i have a mockConfiguration class that has just debounce time value to 0. So no more values on many services and a simple way to control it on tests.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found