Using Angular fixture.whenStable synchronously

I have a synchronous test of the form:

it('should do things' () => {
  const compiled = fixture.debugElement.nativeElement;

  button = compiled.querySelector('#buttonid');
  button.click();

  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(state).toBe(whatIwant);
  }

  button.click();

  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(state).toBe(whatIwant);
  }

});

It works, but I don’t understand why.

Everything I read online indicates that whenStable should only be used in an async test, but the above test does not wrap the testing function with the async() wrapper. If I do that, the test fails (that is, the expects fail because those changes to not appear to be reflected in the component yet).

According to another answer here, using the whenStable method in a synchronous test is pointless:
Does fixture.whenStable() actually do anything in my angular tests if not within an async test execution zone?

No the whenStable() does nothing if you test without async of
fakeAsync. What whenStable() does is to wait for all tasks in the test
NgZone to complete. When you don’t test with async the NgZone does not
get created at all and whenStable() just returns immediately.

However, if I take their word for it, and I omit the whenStable wrapper, and just make the assertions after calling fixture.detectChanges(), the test fails.

So, to summarize:

  • When I use async and whenStable together, the test fails.
  • When I use no async or whenStable, the test fails.
  • When I use no async and whenStable, the test passes: by the time I make each check on the state of the component, the state has been updated to what I expect.

This test only passes when I use whenStable. What I’d like to know is: why?

So, it seems as though, in contradiction to the accepted answer on the above question, whenStable is doing something here. What is that thing, exactly? Does the context I’ve omitted here (what happens upon clicking a button, etc.) matter?

According to the Angular documentation: https://angular.io/guide/testing

The fixture.whenStable() returns a promise that resolves when the JavaScript engine’s task queue becomes empty.

I’m unsure what this means exactly: can anybody clarify?

Source: New feed
Source Url Using Angular fixture.whenStable synchronously