如何为带@Getter@Builder的Java Bean实现SonarQube 100%代码覆盖率
解决方案
方案一:移除@Getter,用Jackson字段序列化替代
问题核心是Jackson默认依赖getter方法完成对象序列化,所以移除@Getter后第三方接口会收到null值。可以通过两种方式让Jackson直接读取私有字段,无需getter:
- 给字段添加@JsonProperty注解
修改MyBody和MyHeader类,直接在私有字段上标记@JsonProperty,Jackson会直接读取字段值完成序列化:
@Builder public class MyBody { @JsonProperty("accountNumber") private String accountNumber; }
@Builder public class MyHeader { @JsonProperty("username") private String username; @JsonProperty("password") private String password; }
这种方式不需要@Getter,Jackson也能正常序列化字段,第三方接口可以收到正确值。
- 全局配置Jackson允许访问私有字段
如果不想给每个字段加注解,可以在Jackson的ObjectMapper中开启全局私有字段访问权限:
ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
配置后Jackson会直接读取所有类的私有字段,无需依赖getter或字段注解,适合批量处理多个类的场景。
方案二:保留@Getter,补充测试覆盖getter方法
如果不想修改现有注解配置,可以通过以下测试方式让SonarQube识别getter方法的测试覆盖:
- 显式调用getter的单元测试
编写简单的单元测试,直接调用MyBody和MyHeader的getter方法:
@Test void testMyBodyGetter() { MyBody body = MyBody.builder().accountNumber("12345").build(); assertEquals("12345", body.getAccountNumber()); } @Test void testMyHeaderGetter() { MyHeader header = MyHeader.builder().username("someusername").password("somepassword").build(); assertEquals("someusername", header.getUsername()); assertEquals("somepassword", header.getPassword()); }
这种方式直接覆盖getter方法,SonarQube会标记这些方法已被测试覆盖。
- 测试序列化流程(贴近真实业务场景)
模拟真实的对象转JSON流程,验证序列化结果的正确性,这个过程中Jackson会自动调用getter方法,SonarQube会统计到方法覆盖:
@Test void testMyBodySerialization() throws JsonProcessingException { MyBody body = MyBody.builder().accountNumber("12345").build(); ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(body); assertTrue(json.contains("\"accountNumber\":\"12345\"")); } @Test void testMyHeaderSerialization() throws JsonProcessingException { MyHeader header = MyHeader.builder().username("someusername").password("somepassword").build(); ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(header); assertTrue(json.contains("\"username\":\"someusername\"")); assertTrue(json.contains("\"password\":\"somepassword\"")); }
这种测试既验证了序列化逻辑的正确性,又间接完成了getter方法的覆盖,比单纯调用getter更有业务价值。
内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan
相关产品推荐
相关产品推荐

