使用Mockito/JUnit5测试时,为实体添加测试专用Setter是否可行?
为测试给JPA实体添加专用Setter方法是否合理?
问题描述
我正在使用Mockito和JUnit5进行单元测试,需要根据用户的createdAt字段与当前日期获取历史学习记录。但User实体的createdAt字段由JPAAuditing自动设置且不可更新,无法直接修改以测试不同场景,因此我在User实体中添加了setCreatedAtForTest等测试专用Setter方法,在测试代码中通过该方法设置指定的createdAt值,相关代码如下:
User实体关键代码
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) @CreatedDate @Column(updatable = false) private LocalDateTime createdAt; public void setCreatedAtForTest(LocalDateTime localDateTime) { this.createdAt = localDateTime; }
测试代码片段
@DisplayName("공부한 날짜 기록을 가져온다.") @Test void getStudyRecords() { User user = UserFixture.getVerifiedUser(); user.setCreatedAtForTest(LocalDateTime.of(2023, 01, 01, 00, 00)); // 其余测试逻辑 }
现咨询这种仅为测试添加Setter方法的做法是否合理。
回答
这种做法是合理且实用的,同时可以通过一些细节优化降低潜在风险:
- 直接解决测试痛点:针对JPA审计字段无法手动修改的问题,这种方式最直接,测试代码无需复杂的mock或者配置调整,可读性和维护性都不错。
- 做好边界控制:给方法加上
ForTest的命名后缀已经很清晰,还可以进一步优化:- 把方法访问权限设为包私有,缩小可调用范围;
- 加上
@VisibleForTesting注解(比如Guava或Spring提供的注解),明确标记这是测试专用方法,IDE和静态检查工具会给出提示,避免生产代码误调用。
- 替代方案参考:如果不想修改实体类,也可以试试这些方式,但各有优缺点:
- 自定义测试用的审计配置:在测试环境中替换JPAAuditing的日期生成逻辑,比如固定返回指定日期,但需要额外的测试配置类;
- 反射修改字段:用反射直接设置
createdAt的值,但可读性差,且字段权限变更时容易导致测试失败; - 增强Fixture构建器:让
UserFixture的构建方法支持传入createdAt,通过实体的私有构造器或者Builder模式设置字段,不过这需要调整实体类的构造逻辑。
总体来说,添加测试专用Setter是性价比很高的方案,只要做好标记和权限控制,不会对生产代码造成负面影响。
内容的提问来源于stack exchange,提问作者Byeongsu KIM
相关产品推荐
相关产品推荐

