简体   繁体   中英

EqualsVerifier in SpringBoot

I am creating the tests for two classes that share a list of data. When I use EqualsVerifier I get an error because it is asking me for a list with data shared by these two classes.

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

My problem: What do I have to change or add in EqualsVerifier to solve the problem?

Creator of EqualsVerifier here.

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:

CustomerView has a reference to YearConfigView (or perhaps List<YearConfigView> ), and YearConfigView has a reference to CustomerView .

EqualsVerifier, while doing its thing, tries to make instances of the classes it's verifying, and giving its fields proper values too. 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.

The way to avoid this, is by giving EqualsVerifier some 'prefab values'. I see you've already tried to do something like this, by adding .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. In any event, you shouldn't give generic prefab values or regular prefab values for the class you're testing.

In general, though, your tests should both give a prefab value for the other 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.

For more information, see the relevant page in the EqualsVerifier documentation . Since the classes are JPA entities, this page might also be helpful: it explains how the @Id is treated by EqualsVerifier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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