← 返回笔记首页

单元测试 vs 集成测试

核心区别在于测试边界,而不是"调用方法的数量"

单元测试 (Unit Test)

测试单个模块/函数隔离环境中的行为。外部依赖(数据库、网络、其他服务)全部用 mock 替代。

// 测试 discountCalculator 的纯逻辑,数据库被 mock 掉
jest.mock('../database/pool');

test('10% discount on $100 = $90', () => {
  expect(calculateDiscount(100, 0.1)).toBe(90);
});

关键特征:快、确定性强、失败时能精确定位到哪个函数出了问题。

测试代码 被测函数 [Mock] 数据库
            [Mock] 外部 API
            [Mock] 其他服务
红色 = Mock   绿色 = 真实

集成测试 (Integration Test)

测试多个真实组件协作时的行为。至少有一个外部依赖是真实的(真实数据库、真实 HTTP 调用等)。

// 真实连接数据库,测试 API → 路由 → 中间件 → 数据库 的完整链路
test('POST /api/appointments creates record in DB', async () => {
  const res = await request(app)
    .post('/api/appointments')
    .send({ /* ... */ });

  expect(res.status).toBe(201);

  // 验证数据库中确实写入了记录
  const row = await db.query(
    'SELECT * FROM appointments WHERE id = $1',
    [res.body.id]
  );
  expect(row.rows).toHaveLength(1);
});

关键特征:慢、可能因环境问题失败,但能发现组件之间的接口不匹配、数据格式错误、SQL 语句问题等单元测试发现不了的 bug。

测试代码 HTTP 请求 Express 路由 中间件 业务逻辑 PostgreSQL
全链路真实组件,无 Mock

核心对比

单元测试 集成测试
外部依赖 全部 mock 至少部分真实
测试目标 单个函数/类的逻辑正确性 组件之间的协作是否正常
典型发现的 bug 算法错误、边界条件 SQL 写错、接口参数不匹配、中间件顺序错误
速度 毫秒级 秒级(涉及数据库/网络)
失败定位 精确到函数 只知道某条链路断了,需要排查
关键判断标准

"连续调用多个方法"本身构成集成测试——如果那些方法的依赖都被 mock 了,它仍然是单元测试。
是否使用真实的外部依赖才是分界线。

Celoria 项目中的对应关系

类型 目录 特征
单元测试 backend/tests/unit/ Mock 了数据库(jest.mock),测试纯业务逻辑
集成测试 backend/tests/integration/ 真实连接 PostgreSQL,测试完整请求链路
API 测试 backend/tests/api/ Mock 了数据库(supertest / mock req/res),测试 HTTP 请求/响应链路和状态码