EqualsVerifier 提供对 JPA 实体的改进支持

EqualsVerifier 库概述

EqualsVerifier 是一个用于 Java 单元测试的库,主要用于自动验证 equals() 方法的实现,并确保 equals()hashCode() 方法达到 100% 的代码覆盖率。最新版本增强了对 Java Persistence Architecture (JPA) 和 Jakarta Persistence 规范的支持。

版本更新与改进

版本 3.15 的主要变化

  • 强制使用 getter 方法:在 JPA 实体中,所有映射字段(如 @OneToMany@ManyToOne)的 equals() 方法必须使用 getter 方法,而不是直接访问字段。这一要求与 FetchType.LAZYFetchType.EAGER 策略无关,因为即使使用 EAGER 策略,某些字段仍可能为 null
  • 禁用新行为:如果不需要该行为,可以通过 suppress(Warning.JPA_GETTER) 来禁用。
  • 新增方法:引入了 withFieldnameToGetterConverter() 方法,允许自定义从字段名派生 getter 名的方式。

版本 3.15.1 的修复

  • 未使用的映射字段问题:修复了当 JPA 实体中未使用的映射字段的 getter 方法未在 equals()hashCode() 方法中使用时抛出错误的问题。

版本 3.15.2 的修复

  • 严格哈希码问题:修复了即使抑制了 Warning.STRICT_HASHCODE,当 hashCode() 方法未使用 JPA 实体的所有字段时仍抛出错误的问题。

使用方法

Maven 依赖

可以通过以下 Maven 依赖引入 EqualsVerifier:

<dependency>
    <groupId>nl.jqno.equalsverifier</groupId>
    <artifactId>equalsverifier</artifactId>
    <version>3.15.2</version>
    <scope>test</scope>
</dependency>

或者使用不带传递依赖的 fat jar:

<dependency>
    <groupId>nl.jqno.equalsverifier</groupId>
    <artifactId>equalsverifier-nodep</artifactId>
    <version>3.15.2</version>
    <scope>test</scope>
</dependency>

示例代码

错误示例

以下 Student 类的 equals() 方法存在错误:

class Student {
    private String firstName;
    private String lastName;

    public Student(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Student student)) {
            return false;
        }
        return firstName == student.firstName && 
            lastName == student.firstName;
    }
}

使用 EqualsVerifier 进行测试时会抛出断言错误。

修复后的示例

通过添加 final 关键字并正确实现 equals()hashCode() 方法修复问题:

class FixedStudent {
    private final String firstName;
    private final String lastName;

    public FixedStudent(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public final boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof FixedStudent)) return false;
        FixedStudent that = (FixedStudent) o;
        return Objects.equals(firstName, that.firstName) &&
            Objects.equals(lastName, that.lastName);
    }

    @Override
    public final int hashCode() {
        return Objects.hash(firstName, lastName);
    }
}

修复后,使用 EqualsVerifier 进行测试时不再抛出错误。

相关资源

  • 开发者:Jan Ouwens,Yoink! 的高级软件开发人员。
  • 官方网站:提供更多信息和详细的手册。
  • 介绍视频:由 Tom Cools 制作的简短介绍视频,教授 EqualsVerifier 的基础知识。
  • GitHub 更新日志:列出所有最近的版本及其更改。
阅读 43
0 条评论