4

我正在tests为共享数据列表的两个类创建。当我使用时,EqualsVerifier我收到一个错误,因为它要求我提供一个包含这两个类共享的数据的列表。

这是错误

Recursive datastructure. Add prefab values for one of the following types: CustomerView, List<YearConfigView>, YearConfigView

这是@Test课程:

@Test
    public void CustomerViewTest() {
EqualsVerifier.forClass(CustomerView.class).withRedefinedSuperclass().withGenericPrefabValues(CustomerView.class).verify();
        }

@Test
    public void YearConfigViewTest() {
        EqualsVerifier.forClass(YearConfigView.class).suppress(Warning.ALL_FIELDS_SHOULD_BE_USED).verify();
    }

CustomerView.java

public class CustomerView extends EntityBase<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private List<YearConfigView> yearConfigs;

    @JsonProperty("current_year_config")
    public YearConfigView getCurrentYearConfig() {
        if (this.getYearConfigs() == null || this.getYearConfigs().isEmpty()) {
            return null;
        }
        int currentYear = LocalDate.now().getYear();
        return this.yearConfigs.parallelStream().filter(yc -> yc.getYear() == currentYear).findAny().orElse(null);
    }
}

YearConfigView.java

public class YearConfigView extends EntityBase<Integer> {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private CustomerView customer;
    private Integer year;
    private String comments;
}

我的问题:我必须更改或添加什么EqualsVerifier来解决问题?

4

1 回答 1

5

EqualsVerifier 的创建者在这里。

没有看到你的类(我想确切地看到哪些字段CustomerViewYearConfigView有,以及如何在两个类上实现equalshashCode实现),很难确定发生了什么,但我怀疑是这样的:

CustomerView引用YearConfigView(或者可能List<YearConfigView>),并且YearConfigView引用CustomerView.

EqualsVerifier 在做它的事情时,会尝试创建它正在验证的类的实例,并给它的字段提供适当的值。为了做到这一点,它必须递归地实例化类的字段并给出这些值。通常,这不是问题,但有时你会遇到一个循环,就像你的情况一样:为了创建一个值 for CustomerView,它必须有一个值 for YearConfigView,反之亦然。

避免这种情况的方法是给 EqualsVerifier 一些“预制值”。我看到您已经尝试通过添加.withGenericPrefabValues(CustomerView.class). (此方法需要 2 个参数,因此我怀疑您可能在将其发布到 StackOverflow 之前删除了一些代码)这仅适用于CustomerView它本身是一个泛型类的情况,我无法验证,因为您没有发布那段特定的代码。无论如何,您不应该为您正在测试的类提供通用预制值或常规预制值。

不过,一般来说,您的测试都应该为另一个类提供一个预制值。看起来像这样:

@Test
public void CustomerViewTest() {
    YearConfigView one = new YearConfigView();
    one.setYear(2020);
    YearConfigView two = new YearConfigView();
    two.setYear(2021);

    EqualsVerifier.forClass(CustomerView.class)
        .withRedefinedSuperclass()
        .withPrefabValues(YearConfigView.class, one, two)
        .verify();
}

@Test
public void YearConfigViewTest() {
    CustomerView one = new CustomerView();
    one.setName("Alice");
    CustomerView two = new CustomerView();
    two.setName("Bob");

    EqualsVerifier.forClass(YearConfigView.class)
        .suppress(Warning.ALL_FIELDS_SHOULD_BE_USED)
        .withPrefabValues(CustomerView.class, one, two)
        .verify();
}

请注意,我仍然不知道您的equals方法中包含哪些字段,因此我只是对如何实例化您的类进行有根据的猜测。

有关详细信息,请参阅EqualsVerifier 文档中的相关页面。由于这些类是 JPA 实体,因此此页面也可能会有所帮助:它解释了@IdEqualsVerifier 如何处理 。

于 2021-03-09T07:28:49.920 回答