Skip to content
Vitest 1
Main Navigation 指南API配置高級
1.6.1
0.34.6

繁體中文

English
简体中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

繁體中文

English
简体中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

外觀

Sidebar Navigation

指南

為什麼使用 Vitest

開始使用

功能特性

工作區

命令列界面

測試過濾器

報告器

覆蓋率

快照

模擬(Mocking)

測試類型

Vitest UI

瀏覽器模式

原始碼測試

測試上下文

測試環境

擴展匹配器

IDE 整合支援

偵錯

與其他測試執行器的比較

遷移指南

常見錯誤

提升效能

API

測試 API 參考文件

模擬函數

Vi

expect

expectTypeOf

assert

assertType

配置

管理 Vitest 配置文件

配置 Vitest

本頁導覽

模擬函數 ​

您可以使用 vi.fn 方法建立一個模擬函數,以追蹤其執行過程。若您想追蹤已建立物件的某個方法,可以使用 vi.spyOn 方法:

js
import { vi } from 'vitest';

const fn = vi.fn();
fn('hello world');
fn.mock.calls[0] === ['hello world'];

const market = {
  getApples: () => 100,
};

const getApplesSpy = vi.spyOn(market, 'getApples');
market.getApples();
getApplesSpy.mock.calls.length === 1;

您應該使用 expect 上的模擬斷言(例如,toHaveBeenCalled)來驗證模擬結果。本 API 參考文件描述了可用於操作模擬行為的屬性和方法。

getMockImplementation ​

  • 類型: (...args: any) => any

返回目前的模擬實作(如果存在)。

如果模擬是使用 vi.fn 建立的,它會將傳入的方法視為模擬實作。

如果模擬是使用 vi.spyOn 建立的,除非提供了自訂實作,否則它會返回 undefined。

getMockName ​

  • 類型: () => string

返回使用 .mockName(name) 方法賦予模擬的名稱。

mockClear ​

  • 類型: () => MockInstance

清除關於每次呼叫的所有資訊。呼叫後,.mock 上的所有屬性都將返回空狀態。如果您需要在不同的斷言之間清除模擬,這會很有用。

如果您希望在每次測試之前自動呼叫此方法,您可以在配置中啟用 clearMocks 設定。

mockName ​

  • 類型: (name: string) => MockInstance

設定模擬的內部名稱。如果斷言失敗,這有助於識別模擬的名稱。

mockImplementation ​

  • 類型: (fn: Function) => MockInstance

接受一個函數,該函數將用作模擬的實作。

ts
import { vi } from 'vitest';
// ---cut---
const mockFn = vi.fn().mockImplementation(apples => apples + 1);
// or: vi.fn(apples => apples + 1);

const NelliesBucket = mockFn(0);
const BobsBucket = mockFn(1);

NelliesBucket === 1; // true
BobsBucket === 2; // true

mockFn.mock.calls[0][0] === 0; // true
mockFn.mock.calls[1][0] === 1; // true

mockImplementationOnce ​

  • 類型: (fn: Function) => MockInstance

接受一個函數,該函數將在下一次呼叫時用作模擬的實作。可以鏈式呼叫,以便多次函數呼叫產生不同的結果。

ts
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
  .fn()
  .mockImplementationOnce(() => true)
  .mockImplementationOnce(() => false);

myMockFn(); // true
myMockFn(); // false

當模擬函數用完所有 mockImplementationOnce 設定的實作後,它會調用使用 vi.fn(() => defaultValue) 或 .mockImplementation(() => defaultValue) 設定的預設實作 (如果它們被呼叫):

ts
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
  .fn(() => 'default')
  .mockImplementationOnce(() => 'first call')
  .mockImplementationOnce(() => 'second call');

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());

withImplementation ​

  • 類型: (fn: Function, callback: () => void) => MockInstance
  • 類型: (fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>

在執行回呼函數時,暫時覆蓋原始模擬實作。

js
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi.fn(() => 'original');

myMockFn.withImplementation(
  () => 'temp',
  () => {
    myMockFn(); // 'temp'
  }
);

myMockFn(); // 'original'

可搭配非同步回呼函數使用。需等待此方法執行完畢,才能恢復使用原始實作。

ts
test('async callback', () => {
  const myMockFn = vi.fn(() => 'original');

  // We await this call since the callback is async
  await myMockFn.withImplementation(
    () => 'temp',
    async () => {
      myMockFn(); // 'temp'
    }
  );

  myMockFn(); // 'original'
});

請留意,此方法優先於 mockImplementationOnce。

mockRejectedValue ​

  • 類型: (value: any) => MockInstance

接受一個值,該值將在呼叫非同步函數時被拒絕 (rejected)。

ts
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));

await asyncMock(); // throws "Async error"

mockRejectedValueOnce ​

  • 類型: (value: any) => MockInstance

接受一個值,該值將在下一次函數呼叫時被拒絕 (rejected)。如果鏈式呼叫,則每次連續呼叫都會拒絕指定的值。

ts
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi
  .fn()
  .mockResolvedValueOnce('first call')
  .mockRejectedValueOnce(new Error('Async error'));

await asyncMock(); // first call
await asyncMock(); // throws "Async error"

mockReset ​

  • 類型: () => MockInstance

執行 mockClear 的操作,並將內部實作重置為一個空函數 (呼叫時返回 undefined)。這也會重置所有 "once" 實作。當您想要將模擬完全重置為預設狀態時,這會很有用。

如果您希望在每次測試之前自動呼叫此方法,您可以在配置中啟用 mockReset 設定。

mockRestore ​

  • 類型: () => MockInstance

執行 mockReset 的操作,並將內部實作恢復為原始函數。

請注意,從 vi.fn() 恢復模擬會將實作設定為返回 undefined 的空函數。恢復 vi.fn(impl) 會將實作恢復為 impl。

如果您希望在每次測試之前自動呼叫此方法,您可以在配置中啟用 restoreMocks 設定。

mockResolvedValue ​

  • 類型: (value: any) => MockInstance

接受一個值,該值將在呼叫非同步函數時被解析 (resolved)。

ts
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi.fn().mockResolvedValue(42);

await asyncMock(); // 42

mockResolvedValueOnce ​

  • 類型: (value: any) => MockInstance

接受一個值,該值將在下一次函數呼叫時被解析 (resolved)。如果鏈式呼叫,則每次連續呼叫都會解析指定的值。

ts
import { vi } from 'vitest';
// ---cut---
const asyncMock = vi
  .fn()
  .mockResolvedValue('default')
  .mockResolvedValueOnce('first call')
  .mockResolvedValueOnce('second call');

await asyncMock(); // first call
await asyncMock(); // second call
await asyncMock(); // default
await asyncMock(); // default

mockReturnThis ​

  • 類型: () => MockInstance

如果您需要從方法返回 this 上下文而不調用實際實作,請使用此方法。這是以下程式碼的簡寫:

ts
spy.mockImplementation(function () {
  return this;
});

mockReturnValue ​

  • 類型: (value: any) => MockInstance

接受一個值,該值將在每次呼叫模擬函數時傳回。

ts
import { vi } from 'vitest';
// ---cut---
const mock = vi.fn();
mock.mockReturnValue(42);
mock(); // 42
mock.mockReturnValue(43);
mock(); // 43

mockReturnValueOnce ​

  • 類型: (value: any) => MockInstance

接受一個值,該值將在下一次函數呼叫時傳回。如果鏈式呼叫,則每次連續呼叫都會傳回指定的值。

當沒有更多 mockReturnValueOnce 值可供使用時,如果存在先前定義的實作,模擬會回退到該實作。

ts
import { vi } from 'vitest';
// ---cut---
const myMockFn = vi
  .fn()
  .mockReturnValue('default')
  .mockReturnValueOnce('first call')
  .mockReturnValueOnce('second call');

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());

mock.calls ​

此為一個陣列,包含每次呼叫的所有引數。陣列中的每個項目是該呼叫的引數列表。

js
const fn = vi.fn();

fn('arg1', 'arg2');
fn('arg3');

fn.mock.calls ===
  [
    ['arg1', 'arg2'], // first call
    ['arg3'], // second call
  ];

mock.lastCall ​

這包含上次呼叫的引數。如果未呼叫模擬,則返回 undefined。

mock.results ​

此為一個陣列,包含從函數 returned 的所有值。陣列的一個項目是一個具有 type 和 value 屬性的物件。可用的類型有:

  • 'return' - 函數正常傳回,沒有拋出錯誤。
  • 'throw' - 函數拋出了一個錯誤。

value 屬性包含返回的值或拋出的錯誤。如果函數返回一個 promise,則 value 將是 已解析 的值,而不是實際的 Promise,除非它從未被解析。

js
const fn = vi
  .fn()
  .mockReturnValueOnce('result')
  .mockImplementationOnce(() => {
    throw new Error('thrown error');
  });

const result = fn(); // returned 'result'

try {
  fn(); // threw Error
} catch {}

fn.mock.results ===
  [
    // first result
    {
      type: 'return',
      value: 'result',
    },
    // last result
    {
      type: 'throw',
      value: Error,
    },
  ];

mock.invocationCallOrder ​

模擬的執行順序。

這會返回一個數字陣列,這些數字在所有已定義的模擬之間共享。

js
const fn1 = vi.fn();
const fn2 = vi.fn();

fn1();
fn2();
fn1();

fn1.mock.invocationCallOrder === [1, 3];
fn2.mock.invocationCallOrder === [2];

mock.instances ​

此為一個陣列,包含在使用 new 關鍵字呼叫模擬時實例化的所有實例。請注意,此為函數的實際上下文 (this),而不是傳回值。

WARNING

如果使用 new MyClass() 實例化模擬,則 mock.instances 將是一個具有一個值的陣列:

js
const MyClass = vi.fn();
const a = new MyClass();

MyClass.mock.instances[0] === a;

如果您從建構函式傳回一個值,它不會在 instances 陣列中,而是在 results 內部:

js
const Spy = vi.fn(() => ({ method: vi.fn() }));
const a = new Spy();

Spy.mock.instances[0] !== a;
Spy.mock.results[0] === a;
Pager
上一頁測試 API 參考文件
下一頁Vi

以 MIT 授權條款 發布。

版權所有 (c) 2024 Mithril Contributors

https://v1.vitest.dev/api/mock

以 MIT 授權條款 發布。

版權所有 (c) 2024 Mithril Contributors