Jest 测试

精选 Jest 测试 常用指令与核心速查备忘单,涵盖高频用法、配置参数与实用技巧。

#Jest 快速概览

Jest 是一个由 Facebook 维护的令人愉悦的 JavaScript 测试框架。它广泛用于现代 JavaScript 和 Node.js 应用中的单元测试集成测试,甚至端到端测试。Jest 提供了一套强大的功能,包括内置测试运行器、断言库、模拟工具、快照测试和测试覆盖率报告。

本指南针对 Jest v20,提供简洁而实用的使用概览。

#关键概念解释

  • describe():用于将相关测试用例分组到测试套件中。
  • test() / it():定义单个测试用例。it() 只是 test() 的 BDD 风格别名。
  • expect():断言库,检查值是否符合预期。
  • beforeEach() / afterEach():在套件中的每个测试之前或之后运行代码。
  • beforeAll() / afterAll():在所有测试之前或之后运行一次设置/清理代码。
  • .only / .skip:聚焦或忽略特定测试/套件。
  • 快照测试:捕获渲染输出并在测试运行之间进行比较。
  • 模拟函数:模拟函数行为或监控函数如何被调用。
  • 定时器模拟:测试基于时间的行为,如 setTimeout()setInterval()
  • 异步测试:编写处理 Promise 或 async/await 的测试。

#🚀 快速开始

npm install --save-dev jest babel-jest

添加到你的 package.json

"scripts": {
  "test": "jest"
}

运行你的测试:

npm test -- --watch

📖 参见:开始使用


#✍️ 编写测试

describe('My work', () => {
  test('works', () => {
    expect(2).toEqual(2);
  });
});
  • describe:对相关测试进行分组。
  • testit:定义单个测试用例。
  • expect:进行断言。

🔄 it()test() 的别名。


#🔧 设置钩子 (Setup Hooks)

用于设置/清理例程:

beforeEach(() => { ... });
afterEach(() => { ... });
beforeAll(() => { ... });
afterAll(() => { ... });

#🎯 聚焦或跳过测试 (Focusing or Skipping Tests)

聚焦测试:

describe.only(...);
it.only(...); // 或 fit()

跳过测试:

describe.skip(...);
it.skip(...); // 或 xit()

#🏁 可选 CLI 标志

标志 描述
--coverage 显示测试覆盖率摘要
--detectOpenHandles 检测未关闭的句柄(例如套接字)
--runInBand 串行运行测试(对 CI 有用)

#✅ 期望值(匹配器)

#基础 (Basic)

expect(value).not.toBe(value);
expect(value).toEqual(value);
expect(value).toBeTruthy();

注意:toEqual 执行深度相等。

#快照 (Snapshots)

expect(value).toMatchSnapshot();
expect(value).toMatchInlineSnapshot();

内联快照需要 Prettier。

#错误 (Errors)

expect(fn).toThrow(error);
expect(fn).toThrowErrorMatchingSnapshot();

#布尔值 (Booleans)

expect(value).toBeFalsy();
expect(value).toBeNull();
expect(value).toBeTruthy();
expect(value).toBeUndefined();
expect(value).toBeDefined();

#数字 (Numbers)

expect(value).toBeCloseTo(number, digits);
expect(value).toBeGreaterThan(number);
expect(value).toBeLessThanOrEqual(number);

#对象 (Objects)

expect(value).toBeInstanceOf(Class);
expect(value).toMatchObject(obj);
expect(value).toHaveProperty('key', value);

#数组/字符串 (Arrays/Strings)

expect(value).toContain(item);
expect(value).toHaveLength(number);
expect(value).toMatch(/pattern/);

#自定义匹配器 (Custom Matchers)

expect.extend(customMatchers);
expect.any(Constructor);
expect.assertions(1);

#⏱️ 异步测试 (Async Tests)

#Promises

test('resolves correctly', () => {
  return somePromise().then(data => {
    expect(data).toEqual(...);
  });
});

#Async/Await

test('awaits correctly', async () => {
  const result = await asyncFunc();
  expect(result).toBe(...);
});

📖 参见:Jest 异步测试


#📸 快照测试 (Snapshot Testing)

it('renders correctly', () => {
  const output = something();
  expect(output).toMatchSnapshot();
});

对于 React 组件:

import renderer from 'react-test-renderer';

it('matches snapshot', () => {
  const tree = renderer.create(<Component />).toJSON();
  expect(tree).toMatchSnapshot();
});

#⏲️ 定时器 (Timers)

jest.useFakeTimers();

it('delays call', () => {
  jest.runOnlyPendingTimers();
  jest.runAllTimers();
});

📖 参见:定时器模拟


#🧪 模拟函数 (Mock Functions)

#创建模拟 (Creating Mocks)

const fn = jest.fn();
const squared = jest.fn((n) => n * n);

#断言 (Assertions)

expect(fn).toHaveBeenCalled();
expect(fn).toHaveBeenCalledTimes(2);
expect(fn).toHaveBeenCalledWith(arg1, arg2);

#灵活匹配器 (Flexible Matchers)

expect(fn).toHaveBeenCalledWith(expect.any(String));
expect(fn).toHaveBeenCalledWith(expect.arrayContaining([1, 2]));

#实例 (Instances)

const MyClass = jest.fn();
const a = new MyClass();
const b = new MyClass();
MyClass.mock.instances; // [a, b]

#调用数据 (Call Data)

fn.mock.calls.length;
fn.mock.calls[0][0];

#返回值 (Return Values)

jest.fn().mockReturnValue('hello');
jest.fn().mockReturnValueOnce('hi');

#模拟实现 (Mock Implementations)

const fn = jest
  .fn()
  .mockImplementationOnce(() => 1)
  .mockImplementationOnce(() => 2);

这份综合指南帮助你开始使用 Jest 测试或像专业人士一样使用它。它与 React Testing Library 完美配合,实现以用户为中心的测试工作流。