Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

Allow using `vi.mock` (and related) functions in tests

未關閉
#32,641 4 則留言 30 個 reaction 已指派 0 人 在 GitHub 檢視

已經有一個關聯 PR 被合併了。

  • #32655 來自 @clydin —— 已合併

評估

難度
5/5
預估耗時
一週以上
新手友好度
20/100
Issue 類型
功能
描述清晰度
需要釐清
活躍度
停滯
技術堆疊
angular, typescript, vite

研究方向

從新的 Angular 單元測試 builder 及其 Vite bundling 路徑開始,接著追蹤 vi.mock 呼叫在哪些地方遭到拒絕,以及 spec 檔案和 setupFiles 如何被轉換。檢視關於編譯期偵測、hoisting、import 重寫和 mock registry 的提議需求。完成的標準是支援列出的 vi 函式,同時保留 ESM live bindings、sourcemaps、coverage,且不使用 runtime module loader。

由索引模型根據 Issue 內容生成。

描述

angular/build:unit-test area: @angular/build
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:

  1. Detect vi.mock() calls at compile time (in spec files, and in setupFiles)
  2. Hoist them
  3. Rewrite import bindings to use a generated mock registry
  4. Replace module resolution during bundling

I suggest to create esbuild plugin, that:

  1. Parse test file AST
  2. Detect:
  • vi.mock()
  • vi.unmock()
  • vi.doMock()
  • vi.doUnmock()
  • vi.importMock()
  • vi.importActual()
  • vi.hoisted()
  1. Hoist mock calls
  2. 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.

主要語言
TypeScript
星號
27k
分支
11.8k
平均合併
17 小時 21 分鐘
30 天內合併 PR
181

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

angular/angular-cli 的其他 Issue

查看 angular/angular-cli 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。