SpringBoot 中的 EqualsVerifier
EqualsVerifier in SpringBoot
我正在为共享数据列表的两个 class 创建 tests
。当我使用 EqualsVerifier
时出现错误,因为它要求我提供包含这两个 classes.
共享数据的列表
这是错误:
Recursive datastructure. Add prefab values for one of the following types: CustomerView, List<YearConfigView>, YearConfigView
这是@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;
}
我的问题:我需要在EqualsVerifier
中更改或添加什么才能解决问题?
这里是 EqualsVerifier 的创建者。
没有看到你的 classes(我想确切地看到 CustomerView
和 YearConfigView
有哪些字段,以及 equals
和 hashCode
classes 上都实现了),很难说到底发生了什么,但我怀疑是这样的:
CustomerView
has a reference to YearConfigView
(or perhaps List<YearConfigView>
), and YearConfigView
has a reference to CustomerView
.
EqualsVerifier 在执行它的操作时,会尝试创建它正在验证的 classes 的实例,并为其字段提供适当的值。为了做到这一点,它必须递归地实例化 class 的字段并给出这些值。通常,这不是问题,但有时您 运行 进入循环,就像您的情况一样:为了为 CustomerView
创建一个值,它必须具有 YearConfigView
的值,反之亦然相反。
避免这种情况的方法是给 EqualsVerifier 一些 'prefab values'。我看到您已经尝试通过添加 .withGenericPrefabValues(CustomerView.class)
来执行类似的操作。 (此方法需要 2 个参数,所以我怀疑您可能在 post 将其发送到 Whosebug 之前删除了一些代码)这仅在 CustomerView
本身是通用 class 时有效,而我不能验证,因为您没有 post 那段特定的代码。在任何情况下,您都不应该为您正在测试的 class 提供通用预制值或常规预制值。
不过,一般来说,您的测试都应该为另一个 class 提供预制值。看起来像这样:
@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
方法中包含哪些字段,因此我只是对如何实例化您的 classes 进行有根据的猜测。
有关详细信息,请参阅 the relevant page in the EqualsVerifier documentation. Since the classes are JPA entities, this page 也可能有帮助:它解释了 EqualsVerifier 如何处理 @Id
。
我正在为共享数据列表的两个 class 创建 tests
。当我使用 EqualsVerifier
时出现错误,因为它要求我提供包含这两个 classes.
这是错误:
Recursive datastructure. Add prefab values for one of the following types: CustomerView, List<YearConfigView>, YearConfigView
这是@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;
}
我的问题:我需要在EqualsVerifier
中更改或添加什么才能解决问题?
这里是 EqualsVerifier 的创建者。
没有看到你的 classes(我想确切地看到 CustomerView
和 YearConfigView
有哪些字段,以及 equals
和 hashCode
classes 上都实现了),很难说到底发生了什么,但我怀疑是这样的:
CustomerView
has a reference toYearConfigView
(or perhapsList<YearConfigView>
), andYearConfigView
has a reference toCustomerView
.
EqualsVerifier 在执行它的操作时,会尝试创建它正在验证的 classes 的实例,并为其字段提供适当的值。为了做到这一点,它必须递归地实例化 class 的字段并给出这些值。通常,这不是问题,但有时您 运行 进入循环,就像您的情况一样:为了为 CustomerView
创建一个值,它必须具有 YearConfigView
的值,反之亦然相反。
避免这种情况的方法是给 EqualsVerifier 一些 'prefab values'。我看到您已经尝试通过添加 .withGenericPrefabValues(CustomerView.class)
来执行类似的操作。 (此方法需要 2 个参数,所以我怀疑您可能在 post 将其发送到 Whosebug 之前删除了一些代码)这仅在 CustomerView
本身是通用 class 时有效,而我不能验证,因为您没有 post 那段特定的代码。在任何情况下,您都不应该为您正在测试的 class 提供通用预制值或常规预制值。
不过,一般来说,您的测试都应该为另一个 class 提供预制值。看起来像这样:
@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
方法中包含哪些字段,因此我只是对如何实例化您的 classes 进行有根据的猜测。
有关详细信息,请参阅 the relevant page in the EqualsVerifier documentation. Since the classes are JPA entities, this page 也可能有帮助:它解释了 EqualsVerifier 如何处理 @Id
。