Skip to content
Vitest 0
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

快速开始

特性

工作区

命令行界面

测试筛选

代码覆盖率

快照(Snapshot)

模拟(Mocking)

类型测试

Vitest UI

浏览器模式(实验性)

源码内测试

测试上下文

测试环境

扩展匹配器

IDE 集成

调试

与其他测试运行器的比较

迁移指南

常见错误

API

测试 API 索引

Mock Functions

Vi

expect

expectTypeOf

assertType

配置

配置 Vitest

页面导航

Mock Functions ​

你可以使用 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 中使用间谍断言来断言 spy 的结果。此 API 参考描述了可用于操作 spy 行为的可用属性和方法。

getMockName ​

  • 类型: () => string

    返回通过 .mockName(name) 方法设置的模拟名称。

mockClear ​

  • 类型: () => MockInstance

    清除关于每次调用的所有信息。调用该方法后,spy.mock.calls 和 spy.mock.results 将返回空数组。这在需要在不同断言之间清理 spy 时非常有用。

    如果你希望在每次测试之前自动调用此方法,你可以在配置中启用 clearMocks 设置。

mockName ​

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

    设置内部模拟名称。便于在断言失败时识别是哪个模拟出了问题。

mockImplementation ​

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

    接受一个函数,该函数将用作模拟的实现。

    例如:

    ts
    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
    const myMockFn = vi
      .fn()
      .mockImplementationOnce(() => true)
      .mockImplementationOnce(() => false);
    
    myMockFn(); // true
    myMockFn(); // false

    当模拟函数的单次调用实现用尽时,它将调用使用 vi.fn(() => defaultValue) 或 .mockImplementation(() => defaultValue) 设置的默认实现(如果已设置)。

    ts
    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
    const myMockFn = vi.fn(() => 'original');
    
    myMockFn.withImplementation(
      () => 'temp',
      () => {
        myMockFn(); // 'temp'
      }
    );
    
    myMockFn(); // 'original'

    可以与异步回调一起使用。需要等待该方法执行完成后才能继续使用原始实现。

    ts
    test('async callback', () => {
      const myMockFn = vi.fn(() => 'original');
    
      // 因为回调是异步的,所以我们需要 await 这个调用
      await myMockFn.withImplementation(
        () => 'temp',
        async () => {
          myMockFn(); // 'temp'
        }
      );
    
      myMockFn(); // 'original'
    });

    此外,它优先于 mockImplementationOnce。

mockRejectedValue ​

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

    接受一个值,当调用异步函数时,返回一个 rejected 状态的 Promise,并将该值作为拒绝原因。

    ts
    const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'));
    
    await asyncMock(); // throws "Async error"

mockRejectedValueOnce ​

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

    接受一个值,该值将导致模拟函数的单次调用返回一个 rejected 状态的 Promise。如果链式调用,则后续每次调用都将以传递的值作为拒绝原因。

    ts
    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)。当你需要将模拟完全重置回初始状态时,这非常有用。

    如果你希望在每次测试之前自动调用此方法,你可以在配置中启用 mockReset 设置。

mockRestore ​

  • 类型: () => MockInstance

    执行与 mockReset 相同的操作,并将内部实现恢复为原始函数。

    请注意,从 vi.fn() 恢复 mock 会将实现设置为空函数,该函数返回 undefined。恢复 vi.fn(impl) 会将实现恢复为 impl。

    如果你希望在每次测试之前自动调用此方法,你可以在配置中启用 restoreMocks 设置。

mockResolvedValue ​

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

    接受一个值,当调用异步函数时,返回一个 resolved 状态的 Promise,并将该值作为解析结果。

    ts
    const asyncMock = vi.fn().mockResolvedValue(43);
    
    await asyncMock(); // 43

mockResolvedValueOnce ​

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

    接受一个值,该值将作为模拟函数的单次调用解析结果。如果链式调用,则后续每次调用都将以传递的值作为解析结果。

    ts
    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 上下文。

mockReturnValue ​

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

    接受一个值,该值将在每次调用模拟函数时被返回。

    ts
    const mock = vi.fn();
    mock.mockReturnValue(42);
    mock(); // 42
    mock.mockReturnValue(43);
    mock(); // 43

mockReturnValueOnce ​

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

    接受一个值,该值将作为模拟函数的单次调用返回值。如果链式调用,则后续每次调用都将返回传递的值。当 mockReturnValueOnce 的值用尽时,将调用由 mockImplementation 或其他 mockReturn* 方法指定的函数。

    ts
    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', 'arg4');

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

mock.lastCall ​

这里存储着上次调用时传递给模拟函数的参数。如果 spy 未被调用,将返回 undefined。

mock.results ​

这是一个数组,其中包含函数每次调用的结果。数组中的每个元素都是一个对象,包含 type 和 value 属性。可用的类型有:

  • 'return' - 函数正常返回。
  • 'throw' - 函数抛出了一个值。

value 属性包含返回值或抛出的错误。如果函数返回一个 Promise,当 Promise 被 resolve 后,value 属性将变为 Promise 的 resolve 值。

js
const fn = vi.fn();

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.instances ​

这是一个数组,其中包含通过 new 关键字调用 mock 函数时创建的所有实例。请注意,这是函数的实际上下文(this),而不是返回值。

WARNING

如果使用 new MyClass() 实例化 mock,则 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://v0.vitest.dev/api/mock

基于 MIT 许可证 发布。

版权所有 (c) 2024 Mithril Contributors