AssertJ:如何构建自定义断言和嵌套断言



我需要将一个PatientDTO dto对象与另一个PatientModel model对象进行比较。

两个类别非常相似:

class PatientDTO {
private String name;
private List<AddressDTO> address;
// Constructors, getters and setters
}
class PatientModel {
private String id;
private String nameElement;
private List<AddressModel> addressElement;
// Constructors, getters and setters
}
class AddressDTO {
private String city;
private String country;
private List<String> linesElement;
// Constructors, getters and setters
}
class AddressModel {
private String city;
private String countryElement;
private List<String> linesElement;
// Constructors, getters and setters
}

主要区别在于:

  • DTO上不存在某些字段:PatientDTO.id不存在
  • 某些字段名称包含Model类的后缀:PatientDTO.name <> PatientModel.nameElement

我喜欢解决的另一个问题是:

  • Address相关断言应共享。我的意思是,类似Address的类存在于其他类中,例如,OrganizationPractitioner

我想建立一个这样的断言:

PatientDTO patientDTO;
PatientModel patientModel;
assertThat(patientDTO).isEqual(patientModel);

不久:

  1. 我应该构建一个自定义断言吗
  2. 我应该为Address有一个断言,还是为Patient有一个包含先前Address断言的断言?我怎么能得到这个
  3. PatientOrganizationAddress断言

我想避免的是这样的代码:

assertThat(patientDTO).anySatisfy(p->{
assertThat(p.getName()).withFailMessage("expected name: "+ p.getAddress().getCity()).isEqualTo(patientModel.getNameElement());
assertThat(p.getAddress().getCity()).withFailMessage("expected city: "+ p.getAddress().getCity()).isEqualTo(patientModel.getCityElement());
assertThat(p.getAddress().getCountry()).withFailMessage("expected country: "+ p.getAddress().getCountry()).isEqualTo(patientModel.getCountryElement());
...
}
);

我想避免上面的代码,因为Patient类确实很大。为了清晰起见,我在这里简称了它们。

有什么想法吗?

逐字段递归比较可以帮助实现这一目的:

PatientDTO patientDTO = new PatientDTO(...);
PatientModel patientModel = new PatientModel(...);
assertThat(patientDTO).usingRecursiveComparison()
.isEqualTo(patientModel);

DTOs上不存在某些字段:PatientDTO.id不存在。

有几种方法可以用于调整比较和忽略字段:

  • 直接使用ignoringFields(String…​ fieldsToIgnore)
  • 通过带有ignoringFieldsMatchingRegexes(String…​ regexes)的正则表达式
  • ignoringFieldsOfTypes(Class…​ typesToIgnore)类型

一些字段名在Model类上包含后缀:PatientDTO.name <> PatientModel.nameElement

当前不支持此操作,在https://stackoverflow.com/a/70381488/9714611.我们计划就此提出一个功能请求,一旦问题链接准备好,我将更新答案。

Address相关断言应共享。我的意思是,类似Address的类存在于其他类中,例如,OrganizationPractitioner。。。

如果目标始终是isEqualTo,那么可能不需要自定义断言实现,只要递归比较关于无法比较具有不同名称的字段的限制不是一个阻碍。在找到更好的解决方案之前,需要对这些字段进行特别比较。

如果目标是用特定于领域的语言提供断言,如:

assertThat(patientDTO).hasAddress(addressDTO);

则可以添加自定义断言实现。

此外,还有一个带有Maven和Gradle插件的断言生成器,可用于基于类属性生成断言。

最新更新