TypeScript 测试:从单元测试到端到端测试——完全指南
\n现代 Web 开发离不开高质量的测试。TypeScript 作为 JavaScript 的超集,提供了强大的类型化工具,但并不能解决逻辑错误问题。在本文中,我们将探讨三个测试层级:单元测试、集成测试和端到端测试。您将学习如何配置环境、编写高效的 TypeScript 测试,并将其集成到 CI/CD 流水线中。
\n\n1. 单元测试:测试金字塔的基础
\n单元测试用于验证独立的模块(函数、类、方法),不依赖外部依赖。对于 TypeScript,最佳选择是 Jest——它原生支持 TypeScript,并提供丰富的 API 用于模拟和断言。
\n\n为 TypeScript 配置 Jest
\nnpm install --save-dev jest @types/jest ts-jest\nnpx ts-jest config:init\njest.config.ts 文件应包含:
export default {\n preset: 'ts-jest',\n testEnvironment: 'node',\n roots: ['<rootDir>/src'],\n testMatch: ['**/__tests__/**/*.test.ts']\n};\n\n函数单元测试示例
\n假设我们有一个计算折扣的函数:
\n// src/utils/discount.ts\nexport function calculateDiscount(price: number, percent: number): number {\n if (percent < 0 || percent > 100) throw new Error('Invalid percent');\n return price - (price * percent) / 100;\n}\n对应的测试:
\n// src/__tests__/discount.test.ts\nimport { calculateDiscount } from '../utils/discount';\n\ndescribe('calculateDiscount', () => {\n it('价格 100 且折扣 20% 时应返回 80', () => {\n expect(calculateDiscount(100, 20)).toBe(80);\n });\n\n it('百分比无效时应抛出错误', () => {\n expect(() => calculateDiscount(100, 150)).toThrow('Invalid percent');\n });\n\n it('折扣 100% 时应返回 0', () => {\n expect(calculateDiscount(50, 100)).toBe(0);\n });\n});\n\n使用模拟(Mock)
\n为了隔离测试,请使用模拟。以下是一个依赖数据库的服务示例:
\n// src/services/user.service.ts\nimport { db } from '../database';\n\nexport class UserService {\n async getUser(id: number) {\n const user = await db.findUser(id);\n if (!user) throw new Error('User not found');\n return user;\n }\n}\n// src/__tests__/user.service.test.ts\nimport { UserService } from '../services/user.service';\nimport { db } from '../database';\n\njest.mock('../database');\n\ndescribe('UserService', () => {\n it('应返回用户', async () => {\n const mockUser = { id: 1, name: 'Alice' };\n (db.findUser as jest.Mock).mockResolvedValue(mockUser);\n\n const service = new UserService();\n const result = await service.getUser(1);\n expect(result).toEqual(mockUser);\n });\n});\n\n2. 集成测试:验证组件间的交互
\n集成测试用于验证模块如何协同工作:API 路由、数据库、外部服务。对于基于 Node.js 的 TypeScript 应用程序,通常使用 Supertest 配合 Jest。
\n\n为 Express/NestJS 配置集成测试
\nnpm install --save-dev supertest @types/supertest\nREST API(NestJS)的测试示例:
\n// src/__tests__/app.integration.test.ts\nimport { Test, TestingModule } from '@nestjs/testing';\nimport { INestApplication } from '@nestjs/common';\nimport * as request from 'supertest';\nimport { AppModule } from '../app.module';\n\ndescribe('AppController (e2e)', () => {\n let app: INestApplication;\n\n beforeAll(async () => {\n const moduleFixture: TestingModule = await Test.createTestingModule({\n imports: [AppModule],\n }).compile();\n\n a