Command
generate
Is this a regression?
The previous version in which this bug was not present was
No response
Description
The @schematics/angular:refactor-jasmine-vitest schematic migrates bare spyOn(obj, 'method') calls (no chained .and.* strategy) as a direct mechanical rename to vi.spyOn(obj, 'method').
This silently changes test behavior because the two APIs have opposite defaults. jasmine.spyOn(obj, 'method') original is never called, returns undefined while vi.spyOn(obj, 'method') calls through.
The major problem it requires significant effort to review the test base and adjust all tests after the migration was executed.
Minimal Reproduction
// Given the following Jasmine test:
it('should stub myMethod', () => {
spyOn(service, 'myMethod'); // original is never called — returns undefined
component.doSomething();
expect(service.myMethod).toHaveBeenCalled();
});
// Running ng generate ä@schematics/angular:refactor-jasmine-vitestä currently produces:
it('should stub myMethod', () => {
vi.spyOn(service, 'myMethod'); // original implementation now runs
component.doSomething();
expect(service.myMethod).toHaveBeenCalled();
});
Exception or Error
A bare spyOn(obj, 'method') without any .and.* chain should migrate to vi.spyOn(obj, 'method').mockReturnValue(undefined) to preserve Jasmine's stub-by-default semantics:
it('should stub myMethod', () => {
vi.spyOn(service, 'myMethod').mockReturnValue(undefined); // original is not called
component.doSomething();
expect(service.myMethod).toHaveBeenCalled();
});
Your Environment
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI : 21.2.11
Angular : 21.2.13
Node.js : 24.15.0
Package Manager : yarn 1.22.22
Operating System : darwin arm64
┌───────────────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular/animations │ 21.2.13 │ 21.2.13 │
│ @angular/build │ 21.2.11 │ 21.2.11 │
│ @angular/cdk │ 21.2.11 │ 21.2.11 │
│ @angular/cli │ 21.2.11 │ 21.2.11 │
│ @angular/common │ 21.2.13 │ 21.2.13 │
│ @angular/compiler │ 21.2.13 │ 21.2.13 │
│ @angular/compiler-cli │ 21.2.13 │ 21.2.13 │
│ @angular/core │ 21.2.13 │ 21.2.13 │
│ @angular/forms │ 21.2.13 │ 21.2.13 │
│ @angular/language-service │ 21.2.13 │ 21.2.13 │
│ @angular/platform-browser │ 21.2.13 │ 21.2.13 │
│ @angular/platform-browser-dynamic │ 21.2.13 │ 21.2.13 │
│ @angular/router │ 21.2.13 │ 21.2.13 │
│ rxjs │ 7.8.2 │ 7.8.2 │
│ typescript │ 5.9.3 │ ~5.9.3 │
│ vitest │ 4.1.7 │ 4.1.7 │
│ webpack │ 5.101.3 │ 5.101.3 │
│ zone.js │ 0.15.1 │ 0.15.1 │
└───────────────────────────────────┴───────────────────┴───────────────────┘
Anything else relevant?
No response
Command
generate
Is this a regression?
The previous version in which this bug was not present was
No response
Description
The
@schematics/angular:refactor-jasmine-vitestschematic migrates barespyOn(obj, 'method')calls (no chained.and.*strategy) as a direct mechanical rename tovi.spyOn(obj, 'method').This silently changes test behavior because the two APIs have opposite defaults.
jasmine.spyOn(obj, 'method')original is never called, returns undefined whilevi.spyOn(obj, 'method')calls through.The major problem it requires significant effort to review the test base and adjust all tests after the migration was executed.
Minimal Reproduction
Exception or Error
A bare
spyOn(obj, 'method')without any.and.*chain should migrate tovi.spyOn(obj, 'method').mockReturnValue(undefined)to preserve Jasmine's stub-by-default semantics:Your Environment
Anything else relevant?
No response