Claude Code写单元测试:从踩坑到效率飙升300%

一开始我也以为这玩意儿就是AI搞个测试,有啥难的。结果呢?三个坑,一个没落下。

我手头有个老项目,Spring Boot + JPA + MySQL,代码量大概10万行,测试覆盖率常年3.2%。真的不是不想写,是每次打开IDE就犯困。直到上周,我花了一下午试了试Claude Code——覆盖率从3.2%蹦到了70%左右。虽然没到某些人吹的90%,但效率高太多了。踩过的坑我今天全都抖出来。

第一坑:直接扔代码?别闹,你得会问

我一开始也犯过这个错。把UserService.java丢给Claude Code,心里美滋滋,以为完事了。结果生成的测试跑都跑不通。

“`
我正在用JUnit 5 + Mockito + AssertJ。
项目结构是Maven标准结构。
给UserService写单元测试,重点测边界条件和异常。
“`

看,就这么简单。上下文一给,代码质量直接上了一个档次。

为什么?因为AI跟人一样,你不说清楚它要做什么菜,它只能瞎猜。你至少得告诉它“要辣的”还是“要清淡的”。

第二坑:测试数据生成,烦死个人

这个坑我真的印象深刻。传统方式造测试数据——写一堆Builder,一个实体类弄完就20分钟过去了,还得手动处理关联关系,真的烦得要死。

Claude Code处理这个的方式倒是很省事。我把实体类定义丢给它,说:“为这个实体生成5组测试数据,覆盖正常值、边界值、空值。”它直接生成JSON格式的数据,还能自动处理@OneToMany和@ManyToOne注解的关系。

不过生成的Address里街道名是“测试街道”,看起来有点傻。我后来手动改成了“上海市浦东新区”。但整体省下的时间还是很多——以前手动写20分钟,现在改2分钟。

第三坑:Mock的粒度,别全mocking

另一个坑是,Claude Code默认把所有依赖都mock掉。覆盖率看起来上去了,但跑集成测试时直接崩。一开始我试过让它全mock,结果覆盖率虚高,业务逻辑根本没跑通。

后来我改成只mock外部服务,内部方法用真实调用。来看个对比:

“`java
// ❌ 默认生成的——全mock,覆盖率虚高
@Mock
private UserRepository userRepository;
@Mock
private EmailService emailService;
@Mock
private AuditService auditService;

// ✅ 优化后的——只mock外部依赖
@Mock
private EmailService emailService; // 外部邮件服务,必须mock

@InjectMocks
private UserService userService; // 被测对象,真实调用
“`

优化后测试执行时间从之前的5分钟缩短到30秒左右。因为减少不必要的mock,对象创建开销少了很多。

第四坑:批量生成测试,一个骚操作

这个技巧真的好用。如果你的项目有一堆相似的Service类,比如CRUD操作,可以让Claude Code一次性生成所有测试。

我收集了所有Service类的接口定义,发给它说:“为这些Service生成标准CRUD测试。”它识别出通用模式,生成了一个模板:

“`java
public abstract class BaseServiceTest {
protected abstract Repository getRepository();
protected abstract Service getService();

@Test
public void testCreate() {
T entity = createTestEntity();
T saved = getService().save(entity);
assertThat(saved).isNotNull();
}
}
“`

这个模板可以直接复用,改几个参数就行。我们5个人,以前每人写一套测试要3天,现在用这个模板,一天搞定。

最后说两句

Claude Code确实能省不少事。但记住,工具只是工具,你得知道怎么用。别指望扔进去就完事,你得会问,会调,会改。

对了,还有个坑——生成的测试数据里,日期字段总是“2024-01-01”,看起来贼假。我后来手动改成随机日期,效果更好。

滚动至顶部