测试
让 AI 写可测代码。
测试
这一课你将能做到
- 让 AI 生成覆盖正常、边界、异常三类场景的单元测试
- 识别并修正 AI 生成测试的典型缺陷(测试通过但没验证、mock 过度、边界遗漏)
- 建立「AI 生成测试 + 人工审查」的纪律,确保测试真的有用
为什么要学
AI 是生成单元测试的神器——写测试的痛点(繁琐、重复、覆盖不全)恰好是 AI 的强项。但 AI 生成的测试有个隐蔽的坑:它们经常「看起来都对,实际上什么都没测」。
人话:AI 写的测试就像 AI 写的代码一样,需要审查。一个不验证结果的测试(assertNotNull(result) 就完事),一个 mock 掉所有依赖的测试(测的是 mock 不是代码),一个只测 happy path 的测试(边界全靠运气)——这些测试的存在感比没有还危险,因为它们给你虚假的安全感。
真实项目中,测试是 AI 生成代码的最后一道质量门。没有测试的 AI 代码,就像没有验收报告的施工——看起来盖好了,住进去才知道哪面墙是歪的。
先建立图像
AI 生成测试的质量光谱:
┌─────────────────────────────────────────┐
│ 好测试: │
│ ✓ 验证行为(不只验证返回值不为 null) │
│ ✓ 覆盖边界(空、null、极值、并发) │
│ ✓ 验证异常(抛了正确的异常类型和信息) │
│ ✓ 真实依赖或最小 mock │
├─────────────────────────────────────────┤
│ 坏测试(AI 常犯的): │
│ ✗ assertNotNull 就完事 │
│ ✗ mock 掉所有依赖,测的是 mock │
│ ✗ 只测正常路径,不测边界和异常 │
│ ✗ 测试逻辑复制被测代码的 bug │
└─────────────────────────────────────────┘
跟着做
步骤 1:让 AI 生成三类场景的测试
给一个真实的服务方法,让 AI 生成完整测试:
// 被测方法
public Article publish(Long articleId, Long operatorId) {
Article article = articleMapper.selectById(articleId);
if (article == null) {
throw new BusinessException("文章不存在");
}
if (!article.getAuthorId().equals(operatorId)) {
throw new BusinessException("只能发布自己的文章");
}
if ("PUBLISHED".equals(article.getStatus())) {
throw new BusinessException("文章已发布,不能重复发布");
}
article.setStatus("PUBLISHED");
article.setPublishedAt(LocalDateTime.now());
articleMapper.updateById(article);
return article;
}
提示词:
为上面的 publish 方法生成单元测试,要求:
1. 覆盖正常场景:作者发布自己的草稿文章
2. 覆盖边界场景:文章不存在、非作者操作、已发布状态
3. 覆盖异常场景:数据库操作异常
4. 每个测试验证:返回值、数据库状态变更、异常类型和消息
5. 用 JUnit 5 + Mockito,不要 mock 掉被测方法本身
步骤 2:审查 AI 生成的测试
AI 通常会给出一版「看起来不错」的测试。你要按清单审查:
清单 1:是否验证了行为?
// 差:只验证不抛异常
@Test
void publish_success() {
assertDoesNotThrow(() -> articleService.publish(1L, 1L));
}
// 好:验证状态变更和返回值
@Test
void publish_success() {
Article result = articleService.publish(1L, 1L);
assertEquals("PUBLISHED", result.getStatus());
assertNotNull(result.getPublishedAt());
verify(articleMapper).updateById(argThat(a ->
"PUBLISHED".equals(a.getStatus())
));
}