Skip to content

[Bug]: fakeAsync and tick seem to be not working with compileComponents and DOM interactions #2682

Open
@marcelhohn

Description

@marcelhohn

Version

14.2.2

Steps to reproduce

  1. Clone the repository at https://github.com/marcelhohn/angular-playground/tree/fake-async-jest
  2. Check out the branch fake-async-jest
  3. Run jest

The minimal reproduction example contains one component, which renders a text upon clicking a button. It does so by subscribing to an observable, which is delayed by using the RxJS delay operator:

export class AppComponent {
  showSavedText = signal(false);

  save() {
    of(undefined)
      // if we don't include the delay here, all tests pass
      .pipe(delay(10))
      .subscribe(() => this.showSavedText.set(true));
  }
}
<button (click)="save()">Save</button>
@if (showSavedText()) {
  <p>Saving was successful</p>
}

In a real application this observable could come from a service.

Under certain conditions (see "Actual behavior"), a test using fakeAsync and tick fails unexpectedly:

describe('AppComponent', () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent]
    })
      .compileComponents();

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should show message after saving', fakeAsync(() => {
    // This test fails when using Jest instead of Jasmine and Karma.
    fixture.debugElement.query(By.css('button')).nativeElement.click();

    tick(10);
    fixture.detectChanges();

    expect(fixture.debugElement.query(By.css('p'))).toBeTruthy();
  }));
});

The spec file contains more tests for the same functionality, demonstrating under which exact conditions the test fails.

Expected behavior

The test passes when using Jest

Actual behavior

If we are

  • using Jest instead of Jasmine and Karma and
  • using compileComponents in the test setup and
  • calling TestBed.createComponent outside of fakeAsync and
  • adding delay to the Observable inside our component and
  • using DOM interactions to trigger component methods

fakeAsync and tick do not seem to work and the test fails unexpectedly.

Additional context

To verify that the exact same test which fails unexpectedly using Jest passes when using Jasmine and Karma, you can check out the branch fake-async-jasmine in the abovementioned repository.

Environment

System:
  OS: Windows 10 10.0.19045
  CPU: (16) x64 AMD Ryzen 7 PRO 5850U with Radeon Graphics
Binaries:
  Node: 20.11.1 - ~\AppData\Local\Programs\nodejs\node.EXE
  npm: 10.2.4 - ~\AppData\Local\Programs\nodejs\npm.CMD
npmPackages:
  jest: ^29.7.0 => 29.7.0

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions