chai vs jasmine vs jest vs mocha vs sinon
JavaScript 测试架构选型:运行器、断言库与模拟工具
chaijasminejestmochasinon类似的npm包:

JavaScript 测试架构选型:运行器、断言库与模拟工具

这些库构成了 JavaScript 测试生态的核心基石。jest 是开箱即用的全能框架,mocha 是高度灵活的测试运行器,chai 提供多样的断言风格,sinon 专注于函数模拟与间谍,而 jasmine 则是经典的行为驱动开发套件。它们共同解决了单元测试中的执行、验证和隔离问题。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
chai08,266147 kB913 个月前MIT
jasmine038175.4 kB01 个月前MIT
jest045,3326.59 kB24322 天前MIT
mocha022,8752.31 MB2325 个月前MIT
sinon09,7582.24 MB4615 天前BSD-3-Clause

JavaScript 测试栈深度对比:Jest, Mocha, Chai, Jasmine 与 Sinon

在构建可靠的 JavaScript 应用时,测试工具的选择直接影响开发效率和代码质量。jestmochachaijasminesinon 是生态中最核心的五个包,但它们扮演的角色截然不同。有些是全能框架,有些是专用工具。让我们从架构、语法和实际场景出发,深入对比它们的差异。

🏗️ 架构模式:全能框架 vs 模块化组合

jest 是开箱即用的全能解决方案。

  • 内置测试运行器、断言库和模拟功能。
  • 无需额外配置即可开始编写测试。
// jest: 所有功能内置
test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

jasmine 也是全能框架,但更经典。

  • 内置运行器、断言和间谍函数。
  • 配置相对固定,常见于旧版 Angular 项目。
// jasmine: 内置全局函数
describe('Sum', function() {
  it('adds 1 + 2 to equal 3', function() {
    expect(sum(1, 2)).toEqual(3);
  });
});

mocha 是灵活的测试运行器。

  • 只提供测试结构(describe/it),不含断言或模拟。
  • 需要搭配 chaisinon 使用。
// mocha: 仅定义测试结构
describe('Sum', function() {
  it('adds 1 + 2 to equal 3', function() {
    // 断言需引入 chai
  });
});

chai 是专用断言库。

  • 提供 expect、should、assert 三种风格。
  • 必须与 mocha 等运行器配合。
// chai: 提供断言能力
expect(sum(1, 2)).to.equal(3);

sinon 是专用模拟库。

  • 提供 stub、spy、mock 功能。
  • 常与 mocha + chai 组合使用。
// sinon: 提供模拟能力
const stub = sinon.stub(myObj, 'method');

📝 断言语法:表达力与风格

jest 使用简洁的 expect

  • 语法直观,支持快照测试。
  • 错误信息清晰,自带差分对比。
// jest: 链式断言
expect(user.name).toBe('Alice');
expect(list).toContain('item');

chai 提供自然语言风格的断言。

  • 支持 BDD (expect) 和 TDD (assert) 风格。
  • 可读性极高,类似英语句子。
// chai: 自然语言风格
expect(user).to.have.property('name').that.equals('Alice');

jasmine 使用内置的 expect

  • 语法与 Jest 类似,但匹配器较少。
  • 无需引入额外库。
// jasmine: 内置断言
expect(user.name).toEqual('Alice');

mocha 本身无断言。

  • 依赖 chaiassert 模块。
  • 灵活性高,但需手动集成。
// mocha + chai: 组合使用
expect(result).to.be.ok;

sinon 侧重于行为验证。

  • 验证函数是否被调用、调用次数。
  • 补充断言库的不足。
// sinon: 行为验证
sinon.assert.calledOnce(stub);

🎭 模拟与间谍:隔离外部依赖

jest 内置强大的模拟系统。

  • jest.fn() 创建函数间谍。
  • jest.mock() 自动模拟模块。
// jest: 内置模拟
const mockFn = jest.fn();
jest.mock('axios');

sinon 提供最细粒度的控制。

  • stub 替换函数实现。
  • spy 监控函数调用。
  • mock 设置期望值。
// sinon: 细粒度控制
const stub = sinon.stub(api, 'get').resolves({ data: {} });

jasmine 内置基础的间谍功能。

  • spyOn 监控对象方法。
  • 功能不如 Sinon 强大,但够用。
// jasmine: 内置间谍
spyOn(api, 'get').and.returnValue(Promise.resolve({}));

mocha 无内置模拟。

  • 完全依赖 sinon 或其他库。
  • 保持核心轻量。
// mocha: 需引入 sinon
// 见 sinon 示例

chai 无模拟功能。

  • 专注断言,不处理依赖隔离。
  • 需配合 sinon 使用。
// chai: 无模拟功能
// 仅用于验证结果

⏳ 异步处理:等待与流程控制

jest 自动处理 Promise。

  • 返回 Promise 或使用 async/await
  • 内置超时控制。
// jest: 异步测试
test('fetches data', async () => {
  const data = await fetchData();
  expect(data).toBeDefined();
});

mocha 灵活支持多种异步模式。

  • 支持 callback、Promise、async/await。
  • 需手动调用 done() 如果使用 callback。
// mocha: 多种异步支持
it('fetches data', function(done) {
  fetchData().then(() => done());
});

jasmine 支持 Promise 和 async。

  • 类似 Jest,返回 Promise 即可。
  • 旧版本需使用 async 包。
// jasmine: 异步测试
it('fetches data', async () => {
  const data = await fetchData();
  expect(data).toBeDefined();
});

chai 不处理异步流程。

  • 仅验证最终结果。
  • 依赖运行器处理异步。
// chai: 仅断言结果
expect(result.status).to.equal(200);

sinon 提供假定时器。

  • sinon.useFakeTimers() 控制时间流逝。
  • 适合测试定时任务。
// sinon: 假定时器
const clock = sinon.useFakeTimers();
clock.tick(1000);

📊 总结对比表

特性jestmochachaijasminesinon
类型全能框架测试运行器断言库全能框架模拟库
配置零配置需配置需配合运行器少量配置需配合运行器
断言内置 expect无 (配 Chai)丰富风格内置 expect行为验证
模拟内置 jest.fn无 (配 Sinon)内置 spyOn强大 stub
适用React/VueNode/库配合 MochaAngular/旧项目复杂模拟

💡 架构师建议

jest 是现代前端项目的首选 🚀。 它消除了工具链配置的痛苦,让团队专注于业务逻辑。适合绝大多数 React、Vue 和通用 JavaScript 项目。

mocha + chai + sinon 是经典组合 🛠️。 当你需要极度灵活的运行控制,或在 Node.js 库开发中需要精细的模拟策略时,这个组合依然强大。

jasmine 适合特定场景 📦。 如果你维护旧版 Angular 项目,或偏好不依赖外部配置的经典 BDD 风格,它依然可靠。

最终建议:除非有特殊的遗留系统限制或极端的定制化需求,否则在新项目中优先选择 jest。它的生态活跃度和开箱即用特性能显著降低维护成本。

如何选择: chai vs jasmine vs jest vs mocha vs sinon

  • chai:

    选择 chai 当你配合 mocha 使用时,想要更丰富的断言语法(如 BDD 风格的 expect 或 TDD 风格的 assert)。它适合对断言表达力有特定要求的项目。

  • jasmine:

    选择 jasmine 如果你维护传统的 Angular 项目,或偏好无需额外依赖的内置间谍函数和断言库。它适合习惯经典 BDD 风格且不愿配置 Jest 的团队。

  • jest:

    选择 jest 如果你正在开发 React 或 Vue 项目,希望零配置启动并获得内置的快照测试和模拟功能。它适合追求开发效率和统一工具链的团队。

  • mocha:

    选择 mocha 如果你需要高度定制测试运行流程,或者在 Node.js 库开发中需要更灵活的异步控制。它适合需要组合不同断言库的复杂场景。

  • sinon:

    选择 sinon 当你在使用 mocha 而非 jest 时,需要强大的桩函数(stub)、间谍(spy)和模拟(mock)功能。它适合需要精细控制外部依赖的非 Jest 环境。

chai的README

ChaiJS
chai

Chai is a BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework.

downloads:? node:?
Join the Slack chat Join the Gitter chat OpenCollective Backers

For more information or to download plugins, view the documentation.

What is Chai?

Chai is an assertion library, similar to Node's built-in assert. It makes testing much easier by giving you lots of assertions you can run against your code.

Installation

Node.js

chai is available on npm. To install it, type:

$ npm install --save-dev chai

Browsers

You can also use it within the browser; install via npm and use the index.js file found within the download. For example:

<script src="./node_modules/chai/index.js" type="module"></script>

Usage

Import the library in your code, and then pick one of the styles you'd like to use - either assert, expect or should:

import { assert } from 'chai';  // Using Assert style
import { expect } from 'chai';  // Using Expect style
import { should } from 'chai';  // Using Should style

Register the chai testing style globally

import 'chai/register-assert';  // Using Assert style
import 'chai/register-expect';  // Using Expect style
import 'chai/register-should';  // Using Should style

Import assertion styles as local variables

import { assert } from 'chai';  // Using Assert style
import { expect } from 'chai';  // Using Expect style
import { should } from 'chai';  // Using Should style
should();  // Modifies `Object.prototype`

import { expect, use } from 'chai';  // Creates local variables `expect` and `use`; useful for plugin use

Usage with Mocha

mocha spec.js --require chai/register-assert.js  # Using Assert style
mocha spec.js --require chai/register-expect.js  # Using Expect style
mocha spec.js --require chai/register-should.js  # Using Should style

Read more about these styles in our docs.

Plugins

Chai offers a robust Plugin architecture for extending Chai's assertions and interfaces.

  • Need a plugin? View the official plugin list.
  • Want to build a plugin? Read the plugin api documentation.
  • Have a plugin and want it listed? Simply add the following keywords to your package.json:
    • chai-plugin
    • browser if your plugin works in the browser as well as Node.js
    • browser-only if your plugin does not work with Node.js

Related Projects

Contributing

Thank you very much for considering to contribute!

Please make sure you follow our Code Of Conduct and we also strongly recommend reading our Contributing Guide.

Here are a few issues other contributors frequently ran into when opening pull requests:

  • Please do not commit changes to the chai.js build. We do it once per release.
  • Before pushing your commits, please make sure you rebase them.

Contributors

Please see the full Contributors Graph for our list of contributors.

Core Contributors

Feel free to reach out to any of the core contributors with your questions or concerns. We will do our best to respond in a timely manner.

Keith Cirkel James Garbutt Kristján Oddsson

Core Contributor Alumni

This project would not be what it is without the contributions from our prior core contributors, for whom we are forever grateful:

Jake Luer Veselin Todorov Lucas Fernandes da Costa Grant Snodgrass