TypeScript 测试:单元测试、集成测试和端到端测试

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程
```html

引言:为什么要测试 TypeScript 代码?



TypeScript 是 JavaScript 的超集,增加了静态类型检查。然而,类型并不能保证应用程序逻辑的正确性。在 TypeScript 中进行测试不仅仅是一种“良好实践”,更是维护代码质量、防止回归和加速开发的必要条件。



在本文中,我们将探讨三个主要的测试层级:unit(单元测试)、integration(集成测试)和 e2e(端到端测试)。您将了解使用哪些工具,看到代码示例,并理解如何为您的 TypeScript 项目构建一个平衡的测试策略。



1. TypeScript 中的单元测试



什么是单元测试?

单元测试用于验证独立的模块或函数。它们执行速度快,且不需要外部依赖(数据库、网络、文件系统)。主要目标是确保每一小段代码都能正确运行。



工具:Jest + ts-jest

TypeScript 中最流行的单元测试框架是 Jest 配合转译器 ts-jest。它支持 mock、spy、覆盖率报告,并且与 TypeScript 集成良好。



单元测试示例

假设我们有一个计算折扣的函数:



// discount.tsexport function calculateDiscount(price: number, discountPercent: number): number {  if (price < 0 || discountPercent < 0 || discountPercent > 100) {    throw new Error('Invalid input');  }  return price * (1 - discountPercent / 100);}


编写测试:



// discount.test.tsimport { calculateDiscount } from './discount';

describe('calculateDiscount', () => { it('should apply 10% discount correctly', () => { expect(calculateDiscount(1000, 10)).toBe(900); });

it('should throw error for negative price', () => { expect(() => calculateDiscount(-100, 10)).toThrow('Invalid input'); });

it('should handle 0% discount', () => { expect(calculateDiscount(500, 0)).toBe(500); });});


运行:npx jest。Jest 会自动查找所有 *.test.ts 文件。



单元测试的最佳实践

  • 隔离依赖——对访问数据库或 API 的模块使用 mock(jest.mock)。
  • 测试边界情况——空数组、null、负数。
  • 遵循 FIRST 原则——Fast(快速)、Isolated(隔离)、Repeatable(可重复)、Self-validating(自我验证)、Timely(及时)。
  • 使用 describe/it——使测试结构清晰可读。


2. 集成测试



集成测试验证什么?

集成测试用于验证多个模块之间的交互:控制器 + 服务 + 数据库,或者 API 端点 + 中间件。它们比单元测试慢,但能更可靠地确保组件之间正确协作。



工具:Supertest + Jest + 内存数据库

测试 Express/Node.js API 时,通常使用 Supertest(HTTP 断言)配合 Jest。数据库可以以内存方式启动(例如 mongodb-memory-server 或 sqlite3)。



Express API 的集成测试示例

假设我们有一个简单的用户管理 REST API:



// app.tsimport express from 'express';import { userRouter } from './routes/userRoutes';

const app = express();app.use(express.json());app.use('/api/users', userRouter);

export { app };


使用 Supertest 进行测试:



// user.integration.test.tsimport request from 'supertest';import { app } from '../app';

describe('POST /api/users', () => { it('should create a new user and return 201', async () => {```

博客

书籍推荐