-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Description
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.
After adding zone.js/testing to one of the spec file
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.