TypeScript 测试:单元测试、集成测试、端到端测试(高级水平)

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

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

开始课程

TypeScript 高级测试:从单元测试到端到端测试



测试不仅仅是检查代码是否正常工作,更是专业 TypeScript 开发的基础。在高级水平上,我们从简单的断言转向构建隔离、快速且可靠的测试金字塔。在本文中,我们将使用 TypeScript 生态系统中的最佳工具,剖析单元测试、集成测试和端到端测试的实践方法。



1. 使用 Jest 和 TypeScript 进行高级单元测试



单元测试检查隔离的模块。在 TypeScript 中,关键挑战在于处理依赖关系、类型和异步操作。



1.1. 使用 jest.mocked 进行模拟和类型化

使用 jest.mocked 为模拟对象提供完整的类型化支持。这可以确保你不会调用不存在的方法。



import { fetchUserData } from './api';import { processUser } from './userProcessor';

jest.mock('./api');

const mockedFetchUserData = jest.mocked(fetchUserData);

describe('processUser', () => { it('应该处理用户数据', async () => { const mockUser = { id: 1, name: 'Alice', email: 'alice@test.com' }; mockedFetchUserData.mockResolvedValue(mockUser);

const result = await processUser(1);

expect(result).toEqual({ displayName: 'Alice', contact: 'alice@test.com' }); expect(mockedFetchUserData).toHaveBeenCalledWith(1); });

it('当缺少 email 时应抛出错误', async () => { mockedFetchUserData.mockResolvedValue({ id: 2, name: 'Bob', email: null }); await expect(processUser(2)).rejects.toThrow('Email is required'); });});


1.2. 测试复杂类型和泛型

对于带有泛型的函数,创建辅助测试类型以避免重复。



// 代码function getFirstElement<T>(arr: T[]): T | undefined {  return arr[0];}

// 测试type TestArray = number[];const array: TestArray = [10, 20, 30];

describe('getFirstElement', () => { it('应返回数组的第一个数字元素', () => { const result = getFirstElement(array); expect(result).toBe(10); // TypeScript 自动推断类型为 number });

it('对于空数组应返回 undefined', () => { const result = getFirstElement([]); expect(result).toBeUndefined(); });});


2. 集成测试:数据库和 API



集成测试检查模块(控制器、服务和数据库)之间的交互。对于基于 Node.js 的 TypeScript 应用程序,Jest + Supertest + Testcontainers 组合是理想选择。



2.1. 使用 Testcontainers 配置测试数据库

Testcontainers 在 Docker 中启动 PostgreSQL,确保每个测试都有干净的环境。



import { PostgreSqlContainer, StartedPostgreSqlContainer } from '@testcontainers/postgresql';import { Client } from 'pg';

let container: StartedPostgreSqlContainer;let client: Client;

beforeAll(async () => { container = await new PostgreSqlContainer().start(); client = new Client({ connectionString: container.getConnectionUri() }); await client.connect(); await client.query(` CREATE TABLE users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL ); `);}, 30000); // 超时 30 秒用于下载镜像

afterAll(async () => { await client.end(); await container.stop();});

describe('User Repository', () => { it('应创建并返回用户', async () => { const res = await client.query( `INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *`, ['Test', 'test@example.com'] ); expect(res.rows[0].name).toBe('Test'); });});


2.2. 使用 Supertest 测试 REST API

启动 Express 应用程序并进行测试

博客

书籍推荐