Allow using `vi.mock` (and related) functions in tests
Một pull request liên quan đã được merge.
- #32655 của @clydin — đã merge
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 20/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Cần làm rõ
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- angular, typescript, vite
- Lĩnh vực
- build-system, testing-qa
Hướng nghiên cứu
Bắt đầu với unit-test builder mới của Angular và đường dẫn bundling bằng Vite của nó, sau đó theo dõi nơi các lệnh gọi vi.mock bị từ chối và cách các tệp spec cùng setupFiles được biến đổi. Xem xét các yêu cầu được đề xuất về phát hiện tại thời điểm biên dịch, hoisting, viết lại import và mock registry. Được xem là hoàn thành khi hỗ trợ các hàm vi được liệt kê, đồng thời vẫn giữ nguyên ESM live bindings, sourcemaps, coverage và không có trình tải mô-đun lúc chạy.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Which @angular/* package(s) are relevant/related to the feature request?
core
Description
With the new Angular unit-test builder (Vite), test files are bundled into unified chunks.
Because of this full bundling step:
- ESM modules are statically linked at build time
- There is no runtime module graph available
- vi.mock() cannot intercept module loading
- Mocking entire modules (components/services/modules) is not possible
Currently if we use vi.mock function for automocking component/directives/services/pipes/etc..., we got an error:
Error: The "vi.mock" and related methods are not supported with the Angular unit-test system. Please use Angular TestBed for mocking.
TestBed overrides are insufficient because:
- They replace Angular metadata (providers/imports), not module implementation
- They cannot replace pure TS logic or side effects
- They do not intercept ESM import bindings
Proposed solution
Instead of runtime interception (like Vitest normally does), Angular test builder should:
- Detect
vi.mock()calls at compile time (in spec files, and in setupFiles) - Hoist them
- Rewrite import bindings to use a generated mock registry
- Replace module resolution during bundling
I suggest to create esbuild plugin, that:
- Parse test file AST
- Detect:
vi.mock()vi.unmock()vi.doMock()vi.doUnmock()vi.importMock()vi.importActual()vi.hoisted()
- Hoist mock calls
- Rewrite imports
Example Transform Injectable
Before:
import { MyService } from './my-service';
import { MyOtherService } from './my-other-service';
vi.mock('./my-service', () => ({
MyService:
@Injectable({providedIn: 'root'})
class {
get() { return 'mock'; }
}
}));
vi.mock('./my-other-service');
test(() => {
const myService = new MyService();
const myOtherService = new MyOtherService();
});
After:
// should initialize once in one environment
const __angularViMocks = (globalThis.__angular_vi_mocks ??= new Map<string, any>());
__angularViMocks.set(
'./my-service',
(() => ({
MyService: class {
get() { return 'mock'; }
static ɵprov = {
providedIn: 'root',
factory: () => new this();
};
static ɵfac = () => new this();
}
}))()
);
__angularViMocks.set(
'./my-other-service',
(() => ({
MyOtherService: class {
get = vi.fn(); // maybe better to put `vi.fn()` to MyOtherService.prototype.get = vi.fn();
static ɵprov = {
providedIn: 'root',
factory: () => new this();
};
static ɵfac = () => new this();
}
}))()
);
import * as __angularViActualMod1 from './my-service';
import * as __angularViActualMod2 from './my-other-service';
// We should replace that import in every dependent chunk.
const { MyService } = __angularViMocks.get('./my-service') ?? __angularViActualMod1;
const { MyOtherService } = __angularViMocks.get('./my-other-service') ?? __angularViActualMod2;
Requirements:
- Must mock full implementation (not only metadata) for any modules, as
vi.mock()does - Must stub components, services, modules, pipes, directives both metadata and implementation
- Must preserve ESM live bindings semantics
- Must preserve sourcemaps and coverage
- Must not require runtime module loader
Alternatives considered
Currently we have no choice, but stay with slow and inefficient jest + jest-preset-angular.
I've implemented deep-automocking infrastructure for jest.mock() ng-automocks-jest, it can stub any angular entities, both metadata and implementation.
- Ngôn ngữ chính
- TypeScript
- Star
- 27k
- Fork
- 11.8k
- Merge trung bình
- 16 giờ 21 phút
- Pull request đã merge (30 ngày)
- 170
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của angular/angular-cli
-
Can't use an array of hostnames in --allowedHosts cli parameter in @angular/build:dev-server Đang mởarea: @angular/build gemini-triaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
angular/angular-cli#33955 ·
-
area: @angular/cli gemini-triaged
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
angular/angular-cli#33055 · 1 bình luận · 3 reaction ·
-
angular/build:library area: @angular/build gemini-triaged
angular/angular-cli#34131 · 1 người được giao ·
-
angular/build:library area: @angular/build gemini-triaged
angular/angular-cli#34130 · 1 người được giao ·
-
angular/build:library area: @angular/build gemini-triaged
angular/angular-cli#34128 · 1 người được giao ·
Tất cả issue của angular/angular-cli
Issue tương tự
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 95/100
-
Ecosystem: ClawMetry — the Qwen Code reader is now free and open source (follow-up to #9294 / #9338) Đang mởcategory/integration priority/P3 scope/documentation status/ready-for-human type/feature-request
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 84/100
-
area:auth FE mvp P3
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
klasolsson81/jobbliggaren#1788 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
get-convex/migrations#69 ·
-
accessibility angular bug good first issue typescript ux
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
apache/fineract-backoffice-ui#584 · 1 bình luận ·