Skip to content

Commit d173973

Browse files
committed
fix(@angular/build): conditionally allow vi.mock for non-relative imports
Previously, `vi.mock` and related Vitest mocking APIs were completely disabled, causing errors even for valid use cases like mocking Node.js built-in modules or installed packages. This commit refactors the `vitest-mock-patch` to: - Allow `vi.mock` for non-relative module paths (e.g., 'fs', '@angular/core'). - Continue to block `vi.mock` for relative module paths (e.g., './my-local-module') to enforce the use of Angular TestBed for local dependency mocking. (cherry picked from commit 108fe07)
1 parent e265b1c commit d173973

File tree

2 files changed

+53
-7
lines changed

2 files changed

+53
-7
lines changed

packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,32 @@ export async function getVitestBuildOptions(
156156

157157
const mockPatchContents = `
158158
import { vi } from 'vitest';
159+
159160
const error = new Error(
160-
'The "vi.mock" and related methods are not supported with the Angular unit-test system. Please use Angular TestBed for mocking.');
161-
vi.mock = () => { throw error; };
162-
vi.doMock = () => { throw error; };
163-
vi.importMock = () => { throw error; };
164-
vi.unmock = () => { throw error; };
165-
vi.doUnmock = () => { throw error; };
161+
'The "vi.mock" and related methods are not supported for relative imports with the Angular unit-test system. ' +
162+
'Please use Angular TestBed for mocking dependencies.'
163+
);
164+
165+
// Store original implementations
166+
const { mock, doMock, importMock, unmock, doUnmock } = vi;
167+
168+
function patch(original) {
169+
return (path, ...args) => {
170+
// Check if the path is a string and starts with a character that indicates a relative path.
171+
if (typeof path === 'string' && /^[./]/.test(path)) {
172+
throw error;
173+
}
174+
175+
// Call the original function for non-relative paths.
176+
return original(path, ...args);
177+
};
178+
}
179+
180+
vi.mock = patch(mock);
181+
vi.doMock = patch(doMock);
182+
vi.importMock = patch(importMock);
183+
vi.unmock = patch(unmock);
184+
vi.doUnmock = patch(doUnmock);
166185
`;
167186

168187
return {

packages/angular/build/src/builders/unit-test/tests/behavior/vitest-mock-unsupported_spec.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,35 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => {
3434
`,
3535
);
3636

37-
const { result, logs } = await harness.executeOnce();
37+
const { result } = await harness.executeOnce();
3838
expect(result?.success).toBeFalse();
3939
});
40+
41+
it('should not fail when vi.mock is used with a non-relative path', async () => {
42+
harness.useTarget('test', {
43+
...BASE_OPTIONS,
44+
});
45+
46+
harness.writeFile(
47+
'src/app/mock-non-relative.spec.ts',
48+
`
49+
import { vi } from 'vitest';
50+
vi.mock('@angular/cdk', () => ({}));
51+
describe('Ignored', () => { it('pass', () => expect(true).toBe(true)); });
52+
`,
53+
);
54+
55+
// Overwrite default to avoid noise
56+
harness.writeFile(
57+
'src/app/app.component.spec.ts',
58+
`
59+
import { describe, it, expect } from 'vitest';
60+
describe('Ignored', () => { it('pass', () => expect(true).toBe(true)); });
61+
`,
62+
);
63+
64+
const { result } = await harness.executeOnce();
65+
expect(result?.success).toBeTrue();
66+
});
4067
});
4168
});

0 commit comments

Comments
 (0)