Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
marcelhohn opened this issue Aug 8, 2024 · 3 comments

Comments

@marcelhohn
Copy link

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
@ahnpnl
Copy link
Collaborator

ahnpnl commented Aug 8, 2024

Does it help if your tsconfig for test uses target: ES2016?

@marcelhohn
Copy link
Author

Yes, setting target: "ES2016" in the tsconfig for tests fixed it. Thanks a lot!

@ahnpnl
Copy link
Collaborator

ahnpnl commented Aug 9, 2024

Duplicated with #2010

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants