Bun测试模拟 BunTestMocking

Bun 测试模拟技能是一种用于软件测试的技术,专门在Bun测试框架中实现模拟函数、监视方法调用、模拟模块和创建测试双打,以提高单元测试和集成测试的效率和可靠性。关键词:Bun, 测试模拟, 模拟函数, spyOn, 模块模拟, 测试双打, 单元测试, 软件测试。

测试 0 次安装 0 次浏览 更新于 3/8/2026

名称: Bun 测试模拟 描述: 用于在Bun测试中模拟函数、spyOn、mock.module、实现和测试双打。 版本: 1.0.0

Bun 测试模拟

Bun 提供与Jest兼容的模拟功能,包括 mock()spyOn() 和模块模拟。

模拟函数

import { test, expect, mock } from "bun:test";

// 创建模拟函数
const fn = mock(() => "original");

test("模拟函数", () => {
  fn("arg1", "arg2");

  expect(fn).toHaveBeenCalled();
  expect(fn).toHaveBeenCalledTimes(1);
  expect(fn).toHaveBeenCalledWith("arg1", "arg2");
});

jest.fn() 兼容性

import { test, expect, jest } from "bun:test";

const fn = jest.fn(() => "value");

test("jest.fn 工作", () => {
  const result = fn();
  expect(result).toBe("value");
  expect(fn).toHaveBeenCalled();
});

模拟返回值

const fn = mock();

// 一次返回值
fn.mockReturnValueOnce("first");
fn.mockReturnValueOnce("second");

// 永久返回值
fn.mockReturnValue("default");

// Promise 返回值
fn.mockResolvedValue("resolved");
fn.mockResolvedValueOnce("once");
fn.mockRejectedValue(new Error("fail"));
fn.mockRejectedValueOnce(new Error("once"));

模拟实现

const fn = mock();

// 设置实现
fn.mockImplementation((x) => x * 2);

// 一次实现
fn.mockImplementationOnce((x) => x * 10);

// 链式实现
fn
  .mockImplementationOnce(() => "first")
  .mockImplementationOnce(() => "second")
  .mockImplementation(() => "default");

监视方法

import { test, expect, spyOn } from "bun:test";

const obj = {
  method: () => "original",
};

test("监视方法", () => {
  const spy = spyOn(obj, "method");

  obj.method();

  expect(spy).toHaveBeenCalled();
  expect(obj.method()).toBe("original"); // 仍然工作

  // 覆盖实现
  spy.mockImplementation(() => "mocked");
  expect(obj.method()).toBe("mocked");

  // 恢复
  spy.mockRestore();
  expect(obj.method()).toBe("original");
});

模拟模块

import { test, expect, mock } from "bun:test";

// 模拟整个模块
mock.module("./utils", () => ({
  add: mock(() => 999),
  subtract: mock(() => 0),
}));

// 现在导入使用模拟版本
import { add } from "./utils";

test("模拟模块", () => {
  expect(add(1, 2)).toBe(999);
});

模拟 Node 模块

mock.module("axios", () => ({
  default: {
    get: mock(() => Promise.resolve({ data: "mocked" })),
    post: mock(() => Promise.resolve({ data: "created" })),
  },
}));

使用工厂模拟

mock.module("./config", () => {
  return {
    API_URL: "http://test.local",
    DEBUG: true,
  };
});

模拟断言

const fn = mock();

fn("a", "b");
fn("c", "d");

// 调用计数
expect(fn).toHaveBeenCalled();
expect(fn).toHaveBeenCalledTimes(2);

// 调用参数
expect(fn).toHaveBeenCalledWith("a", "b");
expect(fn).toHaveBeenLastCalledWith("c", "d");
expect(fn).toHaveBeenNthCalledWith(1, "a", "b");

// 返回值
fn.mockReturnValue("result");
fn();
expect(fn).toHaveReturned();
expect(fn).toHaveReturnedWith("result");
expect(fn).toHaveReturnedTimes(1);

模拟属性

const fn = mock(() => "value");

fn("arg1");
fn("arg2");

// 访问调用信息
fn.mock.calls;        // [["arg1"], ["arg2"]]
fn.mock.results;      // [{ type: "return", value: "value" }, ...]
fn.mock.lastCall;     // ["arg2"]

// 清除历史
fn.mockClear();       // 清除调用,保留实现
fn.mockReset();       // 清除调用 + 实现
fn.mockRestore();     // 恢复原始(用于监视)

常见模式

模拟 Fetch

import { test, expect, spyOn } from "bun:test";

test("模拟 fetch", async () => {
  const spy = spyOn(global, "fetch").mockResolvedValue(
    new Response(JSON.stringify({ data: "mocked" }))
  );

  const response = await fetch("/api/data");
  const json = await response.json();

  expect(json.data).toBe("mocked");
  expect(spy).toHaveBeenCalledWith("/api/data");

  spy.mockRestore();
});

模拟 Console

test("模拟 console", () => {
  const spy = spyOn(console, "log");

  console.log("test message");

  expect(spy).toHaveBeenCalledWith("test message");
  spy.mockRestore();
});

模拟类方法

class UserService {
  async getUser(id: string) {
    // 真实实现
  }
}

test("模拟类方法", () => {
  const service = new UserService();
  const spy = spyOn(service, "getUser").mockResolvedValue({
    id: "1",
    name: "Test User",
  });

  const user = await service.getUser("1");

  expect(user.name).toBe("Test User");
  expect(spy).toHaveBeenCalledWith("1");
});

常见错误

错误 原因 修复
Cannot spy on undefined 属性不存在 检查属性名称
Not a function 尝试模拟非函数 使用正确的模拟方法
Already mocked 重复模拟 先使用 mockRestore
Module not found 模块路径错误 检查 mock.module 中的路径

何时加载参考文献

加载 references/mock-api.md 当:

  • 完整模拟/监视 API 参考
  • 高级模拟模式

加载 references/module-mocking.md 当:

  • 复杂模块模拟
  • 提升行为细节