使用Lombok @Data时Jacoco未完全覆盖equals/hashCode的原因排查
解决Lombok @Data生成的equals/hashCode未被Jacoco完全覆盖的问题
你当前的测试用例遗漏了Lombok生成的equals和hashCode方法的几个关键分支场景,以下是具体缺失的测试点及补充方案:
缺失的测试场景
Equals方法未覆盖分支
- 对象与自身比较:equals方法首先会判断
this == obj,这一分支未被测试 - 与null对象比较:equals方法会处理传入null的情况,需验证返回false
- 与不同类实例比较:比如传入普通Object实例,需验证返回false
- 字段为null的情况:当前测试所有字段均为非null值,需测试字段为null时的equals逻辑(如一个对象buildingId为null,另一个相同;或一个null一个非null)
HashCode方法未覆盖分支
- 字段为null时的hashCode生成:需验证包含null字段的对象能正确生成hashCode,且相同null字段的对象hashCode一致
补充后的测试用例
import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; public class ModelTest { @Test void instantiateBuilding2ModelTest(){ // Given String buildingId = "mail@mail.com"; String buildingName ="myBuildingName"; String buildingId2 = "secondmail@mail.com"; String buildingName2 = "secondBuildingName"; String buildinId3 = "thirdmail@mail.com"; String buildingName3 = "thirdBuildingName"; Building2 building2; Building2 building2_2 = new Building2(buildingId2, buildingName2); Building2 building2_3 = new Building2(buildinId3, buildingName3); // Test Getter building2 = new Building2(buildingId, buildingName); assertEquals(building2.getBuildingId(), buildingId); assertEquals(building2.getBuildingName(), buildingName); // Test Setter building2.setBuildingId(buildingId2); building2.setBuildingName(buildingName2); assertEquals(building2.getBuildingId(), buildingId2); assertEquals(building2.getBuildingName(), buildingName2); // Test toString String building2ToString = "Building2(buildingId=" + building2.getBuildingId() + ", buildingName=" + building2.getBuildingName() + ")"; assertEquals(building2.toString(), building2ToString); // Test canEqual assertTrue(building2.canEqual(building2_3) && building2_3.canEqual(building2)); // Test equals assertTrue(building2.equals(building2_2)); assertFalse(building2.equals(building2_3)); // 补充equals测试场景 // 1. 自身比较 assertTrue(building2.equals(building2)); // 2. 与null比较 assertFalse(building2.equals(null)); // 3. 与不同类实例比较 assertFalse(building2.equals(new Object())); // 4. 字段为null的情况 Building2 nullIdBuilding = new Building2(null, buildingName2); Building2 sameNullIdBuilding = new Building2(null, buildingName2); Building2 nullNameBuilding = new Building2(buildingId2, null); assertTrue(nullIdBuilding.equals(sameNullIdBuilding)); assertFalse(building2.equals(nullIdBuilding)); assertFalse(nullIdBuilding.equals(nullNameBuilding)); // Test hashCode assertTrue(building2.hashCode() == building2_2.hashCode()); assertFalse(building2.hashCode() == building2_3.hashCode()); // 补充hashCode测试场景 // 字段为null时的hashCode assertTrue(nullIdBuilding.hashCode() == sameNullIdBuilding.hashCode()); // 自身hashCode一致 int originalHashCode = building2.hashCode(); assertEquals(originalHashCode, building2.hashCode()); } }
说明
Lombok生成的equals方法严格遵循Java规范处理所有边界情况,Jacoco会检测这些分支是否被执行。补充上述测试后,equals和hashCode的所有分支将被完全覆盖。
内容的提问来源于stack exchange,提问作者Robin Joseph
相关产品推荐
相关产品推荐

