BunJest迁移技能 BunJestMigration

这个技能用于帮助开发者将测试套件从 Jest 迁移到 Bun 测试运行器,包括导入兼容性、模拟函数处理、配置转换等。关键词:测试迁移、Jest、Bun、前端测试、自动化测试、软件开发。

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

name: Bun Jest 迁移 description: 在从 Jest 迁移到 Bun 的测试运行器时使用,包括导入兼容性、模拟和配置。 version: 1.0.0

Bun Jest 迁移

Bun 的测试运行器与 Jest 兼容。大多数 Jest 测试无需更改即可运行。

快速迁移

# 1. 移除 Jest 依赖
bun remove jest ts-jest @types/jest babel-jest

# 2. 更新测试脚本
# package.json: "test": "bun test"

# 3. 运行测试
bun test

导入更改

// 之前 (Jest)
import { describe, it, expect, jest } from '@jest/globals';

// 之后 (Bun) - 无需导入,或显式导入:
import { describe, test, expect, mock, spyOn } from "bun:test";

API 兼容性

完全兼容

Jest Bun 注释
describe() describe() 相同
it() / test() test() 使用 test()
expect() expect() 相同的匹配器
beforeAll/Each beforeAll/Each 相同
afterAll/Each afterAll/Each 相同
jest.fn() mock() 使用 mock()
jest.spyOn() spyOn() 相同

需要更改

Jest Bun 等效
jest.mock('module') mock.module('module', () => {...})
jest.useFakeTimers() import { setSystemTime } from "bun:test"
jest.setTimeout() test() 的第三个参数
jest.clearAllMocks() 在每个模拟上调用 .mockClear()

模拟迁移

模拟函数

// Jest
const fn = jest.fn().mockReturnValue('value');

// Bun
const fn = mock(() => 'value');
// 或为了兼容性:
import { jest } from "bun:test";
const fn = jest.fn(() => 'value');

模块模拟

// Jest (顶级提升)
jest.mock('./utils', () => ({
  helper: jest.fn(() => 'mocked')
}));

// Bun (内联,无提升)
import { mock } from "bun:test";
mock.module('./utils', () => ({
  helper: mock(() => 'mocked')
}));

间谍迁移

// Jest
jest.spyOn(console, 'log').mockImplementation(() => {});

// Bun (相同)
spyOn(console, 'log').mockImplementation(() => {});

定时器迁移

// Jest
jest.useFakeTimers();
jest.setSystemTime(new Date('2024-01-01'));
jest.advanceTimersByTime(1000);

// Bun - 支持 Jest 兼容的定时器 API
import { setSystemTime } from "bun:test";
import { jest } from "bun:test";

jest.useFakeTimers();
jest.setSystemTime(new Date('2024-01-01'));
jest.advanceTimersByTime(1000);  // 现在支持

快照测试

// Jest
expect(component).toMatchSnapshot();
expect(data).toMatchInlineSnapshot(`"expected"`);

// Bun (相同)
expect(component).toMatchSnapshot();
expect(data).toMatchInlineSnapshot(`"expected"`);

更新快照:

bun test --update-snapshots

配置迁移

jest.config.js → bunfig.toml

// jest.config.js (之前)
module.exports = {
  testMatch: ['**/*.test.ts'],
  testTimeout: 10000,
  setupFilesAfterEnv: ['./jest.setup.ts'],
  collectCoverage: true,
  coverageThreshold: { global: { lines: 80 } }
};
# bunfig.toml (之后)
[test]
root = "./"
preload = ["./jest.setup.ts"]
timeout = 10000
coverage = true
coverageThreshold = 0.8

常见迁移问题

问题: jest.mock 不工作

// Jest 模拟提升在 Bun 中不存在
// 将 mock.module 放在导入之前或使用动态导入

// 解决方案 1: 在顶部使用 mock.module
mock.module('./api', () => ({ fetch: mock() }));
import { fetch } from './api';

// 解决方案 2: 动态导入
const mockFetch = mock();
mock.module('./api', () => ({ fetch: mockFetch }));
const { fetch } = await import('./api');

问题: 定时器函数缺失

// Bun 定时器支持有限
// 使用 setSystemTime 进行日期模拟
import { setSystemTime } from "bun:test";

beforeEach(() => {
  setSystemTime(new Date('2024-01-01'));
});

afterEach(() => {
  setSystemTime(); // 重置为真实时间
});

问题: 自定义匹配器

// Jest
expect.extend({ toBeWithinRange(received, floor, ceiling) {...} });

// Bun (相同 API)
import { expect } from "bun:test";
expect.extend({
  toBeWithinRange(received, floor, ceiling) {
    const pass = received >= floor && received <= ceiling;
    return {
      pass,
      message: () => `期望 ${received} 在 ${floor}-${ceiling} 范围内`
    };
  }
});

逐步迁移

  1. 移除 Jest 包

    bun remove jest ts-jest @types/jest babel-jest jest-environment-jsdom
    
  2. 更新 package.json

    {
      "scripts": {
        "test": "bun test",
        "test:watch": "bun test --watch",
        "test:coverage": "bun test --coverage"
      }
    }
    
  3. 转换 jest.config.js 为 bunfig.toml

  4. 在测试文件中更新导入

    • 查找/替换 @jest/globalsbun:test
    • 查找/替换 jest.fn()mock()
    • 查找/替换 jest.mock()mock.module()
  5. 运行并修复

    bun test 2>&1 | head -50  # 检查前 50 个错误
    

常见错误

错误 原因 修复
Cannot find module '@jest/globals' 旧导入 使用 bun:test
jest is not defined 全局 jest bun:test 导入
mock.module is not a function 错误导入 import { mock } from "bun:test"
Snapshot mismatch 不同的序列化 使用 --update-snapshots 更新

何时加载参考资料

加载 references/compatibility-matrix.md 当:

  • 完整的 Jest API 兼容性详情
  • 不支持的功能列表
  • 缺失功能的解决方案