Skip to content

fakeAsync/async tests fail with "zone-testing.js is needed" when using @angular/build:unit-test (Angular 21 + Karma) #32121

@amyth91

Description

@amyth91

Which @angular/* package(s) are the source of the bug?

core, zone.js

Is this a regression?

Yes

Description

After upgrading to Angular 21 and migrating tests to the new @angular/build:unit-test builder (with runner: "karma"), tests using fakeAsync() or async() fail at runtime with:

Error: zone-testing.js is needed for the fakeAsync() test helper but could not be found.
Please make sure that your environment includes zone.js/testing

This happens despite explicitly importing zone.js/testing in test.ts. This behavior did not occur with the legacy Karma builder.

angular.json

{
  "projects": {
    "demo": {
      "architect": {
        "test": {
          "builder": "@angular/build:unit-test",
          "options": {
            "runner": "karma",
            "tsConfig": "tsconfig.spec.json",
            "coverage": true
          }
        }
      }
    }
  }
}

test.ts

import 'zone.js';
import 'zone.js/testing';

import { getTestBed, TestBed } from '@angular/core/testing';
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';

getTestBed().initTestEnvironment(
  BrowserTestingModule,
  platformBrowserTesting(),
  {
    teardown: { destroyAfterEach: true }
  }
);
import { fakeAsync, tick } from '@angular/core/testing';

describe('fakeAsync repro', () => {
  it('should work with fakeAsync', fakeAsync(() => {
    let value = false;
    setTimeout(() => (value = true), 0);

    tick();
    expect(value).toBeTrue();
  }));
});

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/stackblitz-starters-d1chcmgs?file=src%2Ftest.ts

Please provide the exception or error you saw

Error: zone-testing.js is needed for the fakeAsync() test helper but could not be found.
        Please make sure that your environment includes zone.js/testing
    at withFakeAsyncTestModule (https://stackblitzstartersd1chcmgs-n4x0--9876--365214aa.local-credentialless.webcontainer.io/base/chunk-INL3WBVE.js:47980:11)
    at fakeAsync (https://stackblitzstartersd1chcmgs-n4x0--9876--365214aa.local-credentialless.webcontainer.io/base/chunk-INL3WBVE.js:47991:10)
    at https://stackblitzstartersd1chcmgs-n4x0--9876--365214aa.local-credentialless.webcontainer.io/base/spec-main-works.spec.js?2097c1b722769132ead2be0383be52d6bb49e2b3:73:46
    at <Jasmine>
    at src/main-works.spec.ts (https://stackblitzstartersd1chcmgs-n4x0--9876--365214aa.local-credentialless.webcontainer.io/base/spec-main-works.spec.js?2097c1b722769132ead2be0383be52d6bb49e2b3:67:5)
    at __require (https://stackblitzstartersd1chcmgs-n4x0--9876--365214aa.local-credentialless.webcontainer.io/base/chunk-INL3WBVE.js:32:50)
    at https://stackblitzstartersd1chcmgs-n4x0--9876--365214aa.local-credentialless.webcontainer.io/base/spec-main-works.spec.js?2097c1b722769132ead2be0383be52d6bb49e2b3:85:16

Please provide the environment you discovered this bug in (run ng version)

_                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI       : 21.0.2
Angular           : 21.0.3
Node.js           : 20.19.1
Package Manager   : npm 10.8.2
Operating System  : linux x64

┌───────────────────────────┬───────────────────┬───────────────────┐
│ Package                   │ Installed Version │ Requested Version │
├───────────────────────────┼───────────────────┼───────────────────┤
│ @angular/animations       │ 21.0.3            │ ^21.0.3           │
│ @angular/build            │ 21.0.2            │ ^21.0.2           │
│ @angular/cli              │ 21.0.2            │ ^21.0.2           │
│ @angular/common           │ 21.0.3            │ ^21.0.3           │
│ @angular/compiler         │ 21.0.3            │ ^21.0.3           │
│ @angular/compiler-cli     │ 21.0.3            │ ^21.0.3           │
│ @angular/core             │ 21.0.3            │ ^21.0.3           │
│ @angular/forms            │ 21.0.3            │ ^21.0.3           │
│ @angular/platform-browser │ 21.0.3            │ ^21.0.3           │
│ @angular/router           │ 21.0.3            │ ^21.0.3           │
│ rxjs                      │ 7.8.2             │ ^7.8.1            │
│ typescript                │ 5.9.3             │ ^5.9.3            │
│ zone.js                   │ 0.16.0            │ ^0.16.0           │
└───────────────────────────┴───────────────────┴───────────────────┘

Anything else?

While investigating this further, I noticed that importing zone.js/testing directly inside an individual spec file makes fakeAsync() work, not just for that files but all spec files, even when it fails globally via test.ts.

Before adding zone.js/testing to spec file.

Image

After adding zone.js/testing to one of the spec file

Image

This feels like a regression or ordering issue in how the new unit-test builder initializes the test environment compared to @angular-devkit/build-angular:karma.

Any suggestions would be helpful.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions