简体   繁体   English

SpringBoot 中的 EqualsVerifier

[英]EqualsVerifier in SpringBoot

I am creating the tests for two classes that share a list of data.我正在为共享数据列表的两个类创建tests When I use EqualsVerifier I get an error because it is asking me for a list with data shared by these two classes.当我使用EqualsVerifier时出现错误,因为它要求我提供一个包含这两个类共享的数据的列表。

This is the error :这是错误

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

This is the @Test class:这是@Test class:

@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 : 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 : 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;
}

My problem: What do I have to change or add in EqualsVerifier to solve the problem?我的问题:我必须在EqualsVerifier中更改或添加什么来解决问题?

Creator of EqualsVerifier here. EqualsVerifier 的创建者在这里。

Without seeing your classes (I'd like to see exactly which fields CustomerView and YearConfigView have, and how equals and hashCode are implemented on both classes), it's hard to say for certain what's going on, but I suspect it's this:没有看到你的类(我想看看CustomerViewYearConfigView有哪些字段,以及如何在两个类上实现equalshashCode ),很难确定发生了什么,但我怀疑是这样的:

CustomerView has a reference to YearConfigView (or perhaps List<YearConfigView> ), and YearConfigView has a reference to CustomerView . CustomerView有对YearConfigView的引用(或者可能是List<YearConfigView> ),并且YearConfigView有对CustomerView的引用。

EqualsVerifier, while doing its thing, tries to make instances of the classes it's verifying, and giving its fields proper values too. EqualsVerifier 在做它的事情时,会尝试创建它正在验证的类的实例,并给它的字段提供适当的值。 In order to do that, it must recursively instantiate the class's fields and give those values too.为了做到这一点,它必须递归地实例化类的字段并给出这些值。 Usually, that's not a problem, but sometimes you run into a loop, like in your case: in order to create a value for CustomerView , it must have a value for YearConfigView and vice versa.通常,这不是问题,但有时你会遇到一个循环,就像你的情况一样:为了为CustomerView创建一个值,它必须有一个YearConfigView的值,反之亦然。

The way to avoid this, is by giving EqualsVerifier some 'prefab values'.避免这种情况的方法是给 EqualsVerifier 一些“预制值”。 I see you've already tried to do something like this, by adding .withGenericPrefabValues(CustomerView.class) .我看到您已经尝试通过添加.withGenericPrefabValues(CustomerView.class)来做这样的事情。 (This method requires 2 parameters so I suspect you may have removed some code before posting it to StackOverflow ) This only works if CustomerView is itself a generic class, which I can't verify because you didn't post that particular piece of code. (此方法需要 2 个参数,因此我怀疑您可能在将其发布到 StackOverflow 之前删除了一些代码)这仅适用于CustomerView本身是通用 class 的情况,我无法验证,因为您没有发布那段特定的代码。 In any event, you shouldn't give generic prefab values or regular prefab values for the class you're testing.无论如何,您不应该为您正在测试的 class 提供通用预制值或常规预制值。

In general, though, your tests should both give a prefab value for the other class.不过,总的来说,您的测试都应该为另一个 class 提供预制值。 That would look like this:看起来像这样:

@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();
}

Note that I still don't know which fields are included in your equals methods, so I'm only making an educated guess about how to instantiate your classes.请注意,我仍然不知道您的equals方法中包含哪些字段,因此我只是对如何实例化您的类进行有根据的猜测。

For more information, see the relevant page in the EqualsVerifier documentation .有关详细信息,请参阅EqualsVerifier 文档中的相关页面 Since the classes are JPA entities, this page might also be helpful: it explains how the @Id is treated by EqualsVerifier.由于这些类是 JPA 实体,因此此页面也可能会有所帮助:它解释了 EqualsVerifier 如何处理@Id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM