为了账号安全,请及时绑定邮箱和手机立即绑定

用 Jest 进行 JavaScript 单元测试入门指南

概述

Jest 是一个由 Facebook 开发的成熟 JavaScript 测试框架,支持多种应用程序和库。它提供零配置、自动检测测试文件和自动重载等功能。Jest 内置了强大的断言库,并能生成详细的代码覆盖率报告。Jest 支持模拟和间谍功能,便于在测试中隔离依赖代码。

Jest 简介

Jest 是什么

Jest 是一个由 Facebook 开发的成熟 JavaScript 测试框架,最初作为 Facebook 的内部工具开发,后来开源并成为 JavaScript 生态系统中广泛使用的工具。Jest 支持多种 JavaScript 应用程序,包括前端和后端应用,以及 Node.js 和 React 应用。

Jest 的主要功能

  1. 零配置:Jest 可直接运行于项目中,无需复杂配置。
  2. 自动检测测试文件:Jest 可自动检测项目中的测试文件,无需手动指定测试文件路径。
  3. 自动重载:在没有配置的情况下,Jest 可自动重载测试文件,当代码更改时,快速执行测试。
  4. 断言库:Jest 内置了强大的断言库,支持多种匹配方式。
  5. 测试覆盖率:Jest 可生成详细的代码覆盖率报告,帮助开发者理解哪些部分代码被测试覆盖。
  6. Mock 和 Spies:Jest 支持模拟和间谍功能,便于在测试中隔离依赖代码。

为什么选择 Jest

  • 易于使用:Jest 提供简洁的 API,使得编写测试变得简单。
  • 强大的功能:除了基本的单元测试,Jest 还支持集成测试、模拟依赖、异步测试等高级功能。
  • 广泛的生态系统:Jest 与许多流行的框架和库(如 React、Vue、Angular)无缝集成。
  • 社区支持:Jest 有一个活跃的社区,社区成员可以提供帮助并贡献功能。
  • 文档丰富:Jest 的官方文档详细且易于理解,提供了大量的示例和教程。
  • 测试覆盖率:Jest 提供详尽的测试覆盖率分析,帮助开发者识别未覆盖的代码区域。

示例项目

假设我们正在构建一个简单的计算器应用,使用 Jest 进行单元测试。这将展示 Jest 在实际项目中的应用。

安装和配置 Jest

使用 npm 或 yarn 安装 Jest

安装 Jest 时,可以通过 npm 或 yarn 安装。以下是使用 npm 安装 Jest 的示例:

npm install --save-dev jest

或者使用 yarn:

yarn add --dev jest

安装完成后,Jest 将作为开发依赖项添加到 package.json 文件中。同时,node_modules 目录中会包含 Jest 及其依赖项。

配置 Jest 项目

Jest 通常不需要配置,但可以根据项目需求进行自定义。Jest 的配置可以通过在项目根目录下创建 jest.config.js 文件来实现。以下是一个简单的 jest.config.js 示例:

module.exports = {
  // 测试文件的根目录
  roots: ['<rootDir>/src'],
  // 测试文件的扩展名
  testMatch: ['**/?(*.)+(spec|test).js'],
  // 用于设置全局的变量
  setupFiles: ['<rootDir>/jest.setup.js'],
  // 自定义的覆盖报告文件名
  coverageReporters: ['text', 'lcov'],
  // 是否使用 TypeScript
  transform: {
    '^.+\\.ts?$': 'ts-jest',
  },
};

初始化 Jest 测试

初始化 Jest 测试时,可以在项目中创建测试文件夹并编写测试文件。通常,测试文件夹命名为 __tests__tests,并在其中编写测试文件。

mkdir __tests__

__tests__ 文件夹中创建一个测试文件 example.test.js

// __tests__/example.test.js
const add = (a, b) => a + b;

describe('add function', () => {
  it('should add two numbers', () => {
    expect(add(1, 2)).toBe(3);
  });
});

使用命令行运行测试:

npx jest

这样,你就可以通过 npx jest 命令来运行测试了。

编写基本测试用例

创建测试文件

可以使用任何命名约定来组织测试文件,但通常推荐将测试文件放在 __tests__tests 文件夹中。例如:

mkdir __tests__

__tests__ 文件夹中创建一个测试文件 math.test.js

// __tests__/math.test.js
const { add, subtract } = require('../src/math');

describe('math operations', () => {
  it('should add two numbers', () => {
    expect(add(2, 3)).toBe(5);
  });

  it('should subtract second number from first', () => {
    expect(subtract(5, 2)).toBe(3);
  });
});

注意,测试文件通常以 .test.js.spec.js 为扩展名。

使用 describe, it, 和 expect

describe 用于定义测试组,it 用于编写具体的测试用例,expect 用于编写断言。

// __tests__/example.test.js

describe('Example Suite', () => {
  it('should test equality', () => {
    expect(1 + 1).toBe(2);
  });

  it('should test inequality', () => {
    expect(1 + 1).not.toBe(3);
  });
});

测试函数和类的基本方法

例如,假设有一个简单的 Calculator 类:

// src/calculator.js
class Calculator {
  add(a, b) {
    return a + b;
  }

  subtract(a, b) {
    return a - b;
  }
}

可以为其编写测试:

// __tests__/calculator.test.js
const { Calculator } = require('../src/calculator');

describe('Calculator', () => {
  it('should add two numbers', () => {
    const calc = new Calculator();
    expect(calc.add(2, 3)).toBe(5);
  });

  it('should subtract second number from first', () => {
    const calc = new Calculator();
    expect(calc.subtract(5, 2)).toBe(3);
  });
});
Jest 的高级功能

使用 mock 和 spies

Mock 函数

Mock 函数用于模拟依赖项或外部调用。例如,假设有一个 fetchData 函数,它依赖于另一个函数 getData

// src/data.js
const getData = () => {
  return 'data';
};

const fetchData = () => {
  return getData();
};

module.exports = {
  fetchData,
};

在测试中可以 mock getData 函数:

// __tests__/data.test.js
const { fetchData } = require('../src/data');

describe('fetchData', () => {
  it('should fetch data using mock', () => {
    jest.mock('../src/data', () => ({
      getData: () => 'mocked data',
    }));

    expect(fetchData()).toBe('mocked data');
  });
});

Spies

Spy 函数用于监视和断言函数的调用。例如:

// __tests__/spy.test.js
describe('Spy example', () => {
  const spy = jest.fn();

  it('should call the spy', () => {
    spy();
    expect(spy).toHaveBeenCalled();
  });
});

测试异步代码

测试异步代码时,可以使用 async/awaitPromise 或 Jest 提供的 done 回调。

// src/promise.js
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

module.exports = delay;

在测试中:

// __tests__/promise.test.js
const delay = require('../src/promise');

describe('delay', () => {
  it('should resolve after the given delay', async () => {
    const result = await delay(200);
    expect(result).toBeUndefined();
  });

  it('should resolve using done', (done) => {
    delay(200).then(() => {
      expect(1).toBe(1);
      done();
    });
  });
});

断言和匹配器

Jest 内置了许多匹配器,可以用来断言测试结果。例如:

// __tests__/assertions.test.js
describe('Assertions', () => {
  it('should use toBe for equality', () => {
    expect(1 + 1).toBe(2);
  });

  it('should use toBeNull for null', () => {
    expect(null).toBeNull();
  });

  it('should use toBeDefined for not undefined', () => {
    expect('hello').toBeDefined();
  });

  it('should use toBeTruthy for truthy values', () => {
    expect('hello').toBeTruthy();
  });

  it('should use toBeFalsy for falsy values', () => {
    expect(0).toBeFalsy();
  });
});

此外,还提供了 toBeCloseTotoContaintoEqualtoThrow 等匹配器,可以用于不同的断言场景。

运行和调试测试

在终端中运行测试

在终端中,可以通过 npx jest 命令运行测试。例如:

npx jest

Jest 将会自动检测项目中的测试文件并运行测试。测试输出将显示在终端中,包括通过的测试、失败的测试以及覆盖率报告。

查看测试覆盖率

Jest 提供了详细的代码覆盖率报告。可以在 package.json 文件中添加 coverageReporters 配置来设置覆盖率报告的格式。例如:

{
  "scripts": {
    "test": "jest",
    "coverage": "jest --coverage"
  },
  "jest": {
    "coverageReporters": ["text", "lcov"]
  }
}

运行 npm run coverageyarn coverage 后,Jest 将生成覆盖率报告。默认情况下,报告会被输出到 coverage 文件夹中。

调试测试代码

为了调试测试代码,可以使用 debugger 关键字插入断点。例如:

// __tests__/debug.test.js
describe('Debugging Example', () => {
  it('should debug a test', () => {
    const a = 1;
    debugger;
    expect(a).toBe(1);
  });
});

运行测试时,调试器会在断点处暂停。可以使用调试工具来检查变量状态、调用堆栈等,以便更好地理解测试行为。

总结和资源推荐

Jest 学习资源

  • 官方文档:Jest 官方文档是学习 Jest 最权威的资源。
  • 慕课网:慕课网提供了多个关于 Jest 的课程,涵盖从基础到高级的各种知识点。
  • GitHub:GitHub 上有许多 Jest 的示例项目,可以参考这些项目了解实际应用。

Jest 社区和文档

  • Jest GitHub:Jest 的 GitHub 仓库包含了大量的文档和示例代码。
  • Stack Overflow:Stack Overflow 上有很多关于 Jest 的问题和解答,可以作为参考。
  • Jest 官方论坛:Jest 官方论坛是一个活跃的社区,可以提问问题并分享经验。

常见问题解答

为什么某些测试用例失败?

  • 检查测试用例:确保测试用例正确地模拟了预期的行为。
  • 检查实际代码:确保实际代码按预期实现了功能。

如何提高测试覆盖率?

  • 编写更多的测试用例:覆盖更多的代码路径。
  • 使用 Jest 的覆盖率报告:分析覆盖率报告,找到未覆盖的代码区域。

Jest 是否支持 TypeScript?

  • 支持:Jest 支持 TypeScript,但需要安装 ts-jest 插件来正确处理 TypeScript 文件。

测试异步代码的最好方法是什么?

  • 使用 async/await:这是处理异步代码的推荐方法。Jest 自动支持 async/await 测试用例。

通过以上内容,你已经掌握了如何使用 Jest 进行 JavaScript 单元测试的基本知识和高级功能。希望能帮助你在项目中应用 Jest 来提高代码质量。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消