You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Lombok @Data的equals方法无法实现100%测试覆盖率的问题咨询

问题描述

我正尝试让使用Lombok @Data注解的Person类的equals方法测试覆盖率达到90%以上,目标是100%,但目前仅能达到75%-80%(仅指equals方法的覆盖率),是不是遗漏了什么?

我找到了一篇关于EqualsVerifier的文章,但不清楚如何在代码中使用它。

我的Person类代码:

@Data
public class Person {
    private String name;
    private int age;
}

我的测试代码:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class PersonTest {

    @Test
    public void testEquals_PositiveScenario() {
        // 创建两个属性相同的Person对象
        Person person1 = new Person("John", 30);
        Person person2 = new Person("John", 30);

        // 验证equals方法返回true
        assertTrue(person1.equals(person2));
    }

    @Test
    public void testEquals_NegativeScenario_DifferentName() {
        // 创建两个姓名不同的Person对象
        Person person1 = new Person("John", 30);
        Person person2 = new Person("Alice", 30);

        // 验证equals方法返回false
        assertFalse(person1.equals(person2));
    }

    @Test
    public void testEquals_NegativeScenario_DifferentAge() {
        // 创建两个年龄不同的Person对象
        Person person1 = new Person("John", 30);
        Person person2 = new Person("John", 25);

        // 验证equals方法返回false
        assertFalse(person1.equals(person2));
    }

    @Test
    public void testEquals_NegativeScenario_NullObject() {
        // 创建一个Person对象
        Person person = new Person("John", 30);

        // 验证和null比较返回false
        assertFalse(person.equals(null));
    }

    @Test
    public void testEquals_NegativeScenario_DifferentClass() {
        // 创建一个Person对象
        Person person = new Person("John", 30);

        // 验证和不同类对象比较返回false
        assertFalse(person.equals(new Object()));
    }
}

请问我是否遗漏了测试场景?该如何正确使用EqualsVerifier来提升equals方法的测试覆盖率?


解答

一、你遗漏的测试场景

Lombok生成的equals方法包含几个未覆盖的分支:

  • 对象自比较:person.equals(person),这个分支直接返回true,当前测试未覆盖
  • name为null的场景:包括两个对象name都为null、一个为null另一个不为null的情况,这部分分支没覆盖

补充以下测试用例后,覆盖率可接近100%:

@Test
public void testEquals_SameObject() {
    Person person = new Person("John", 30);
    assertTrue(person.equals(person));
}

@Test
public void testEquals_NameNull_Both() {
    Person person1 = new Person(null, 30);
    Person person2 = new Person(null, 30);
    assertTrue(person1.equals(person2));
}

@Test
public void testEquals_NameNull_OneSide() {
    Person person1 = new Person(null, 30);
    Person person2 = new Person("John", 30);
    assertFalse(person1.equals(person2));
}

二、使用EqualsVerifier快速拉满覆盖率

EqualsVerifier可以自动覆盖equals方法的所有分支,同时验证equals的契约规范,无需手动编写多个测试用例,步骤如下:

  1. 添加依赖(Maven示例):
<dependency>
    <groupId>nl.jqno.equalsverifier</groupId>
    <artifactId>equalsverifier</artifactId>
    <version>3.15.3</version>
    <scope>test</scope>
</dependency>
  1. 编写测试用例:
import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test;

public class PersonTest {
    @Test
    public void testEqualsContract() {
        EqualsVerifier.forClass(Person.class)
                // 如果name字段不允许为null,添加该行;允许null则去掉
                .withNonnullFields("name")
                .verify();
    }
}

这个测试会自动验证equals方法的自反性、对称性、传递性、一致性等所有规范,同时覆盖所有代码分支,直接将覆盖率拉到100%。

内容的提问来源于stack exchange,提问作者sravan ganji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:40:41