Mocha 单元测试入门指南

Mocha 是 JavaScript 生态最老牌的测试框架之一,以极简内核加自由组合著称。本文讲解 Mocha 环境搭建、编写与运行测试、异步测试、钩子函数,以及配合 Chai 断言与 Sinon 打 Mock。

最佳实践
测试检测与质量验证插画

本文依据官方文档整理,未执行运行验证或性能基准。代码片段展示局部用法,业务函数、数据和环境需按项目补齐;版本与配置以所引文档为准。

直接回答:Mocha 是 JavaScript 生态中最成熟的测试框架之一,它只做一件事——强大而灵活的测试运行器;断言库(Chai)、Mock 工具(Sinon)、测试结构都由你自由选配。 这种"核心极简、外围自选"的哲学让它在需要定制化的 Node.js 项目里长盛不衰。

Mocha 的哲学:自由组合

与 Jest 的"全家桶"相反,Mocha 给你的是一个空架子:

  • 断言:配 Chai(expect(foo).to.equal(3))或 Node 内置 assert;
  • Mock/Spy:配 Sinon;
  • 覆盖率:配 c8 或 nyc。

代价是初始配置多一步,回报是每个环节都可替换、可升级,不被框架绑架。

环境搭建

mkdir mocha-demo && cd mocha-demo
npm init -y
npm pkg set type=module
npm install --save-dev mocha chai sinon

package.json 加脚本:

{
  "scripts": {
    "test": "mocha"
  }
}

Mocha 默认执行 test/ 目录下的文件。

第一条测试

test/math.test.js:

import { expect } from "chai";
import { add } from "../math.js";

describe("add 函数", () => {
  it("1 + 2 应该等于 3", () => {
    expect(add(1, 2)).to.equal(3);
  });
});

此处假定 math.js 用 ESM 导出 add;新版 Chai 使用 ESM,不能沿用旧版 require 示例。describe/it 的骨架与 Jest 相近,区别在于断言来自 Chai。npm test 运行。

异步测试

Mocha 支持三种异步写法,推荐直接用 Promise/async-await:

it("应该返回用户数据", async () => {
  const user = await fetchUser(1);
  expect(user.name).to.equal("Ada");
});

老式回调风格需要在 it 参数里接收 done 并在结束时调用——忘记调用会卡到超时,这也是大家更偏爱 async 写法的原因。默认超时 2 秒,慢测试用 this.timeout(5000) 放宽(注意要用普通函数而非箭头函数)。

钩子:setup 与 teardown

describe("用户仓库", () => {
  before(async () => { /* 套件前一次:建连接 */ });
  beforeEach(async () => { /* 每条前:灌数据 */ });
  afterEach(async () => { /* 每条后:清数据 */ });
  after(async () => { /* 套件后一次:断连接 */ });
});

钩子也可以挂在根层级(任何 describe 之外);串行模式下根钩子可能影响其他文件,跨文件或并行运行时应按 Root Hook Plugins 文档明确作用域。

用 Sinon 打 Mock

import sinon from "sinon";

afterEach(() => sinon.restore());

it("应该调用支付网关", async () => {
  const stub = sinon.stub(gateway, "charge").resolves({ ok: true });

  await orderService.pay(order);

  expect(stub.calledOnceWith(order.id, 9900)).to.be.true;
  // afterEach 保证断言失败时也恢复补丁
});

Sinon 的三件套:spy(监听不改行为)、stub(替换行为)、mock(带期望的组合体)。绝大多数场景一个 stub 就够。

常见问题(FAQ)

Q:Mocha 和 Jest 怎么选?
A:要省心全家桶选 Jest;要自由拼装、对依赖控制严格(比如大型后端项目)选 Mocha。Node 内置 test runner 兴起后,新小项目也可以考虑零依赖路线。

Q:ESM 项目里 Mocha 怎么用?
A:Mocha 支持 ESM,注意 import 路径要带扩展名;配合 --loader 或 mocharc 配置文件处理 TS 等场景。

Q:测试偶发超时怎么排查?
A:可能是异步未等待、资源争抢或外部依赖——漏了 await、回调没调 done、或外部资源没 Mock。先给可疑用例加 this.timeout 确认,再修真正的等待逻辑。

官方参考

资料核对日期:2026-09-29。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台