给定以下类...
public class UserAccount {
private Long id;
private String email;
private String activationCode;
private Date createDate;
}
... 我需要使用 AssertJ 将实际对象与预期对象进行比较。但是,字段 id
、activationCode
和 createDate
具有动态值,我无法将其硬编码到断言中。
所以下面的断言会失败:
assertThat(actualUserAccount).isEqualTo(expectedUserAccount);
然后我发现以下内容会忽略某些字段:
assertThat(actualUserAccount)
.usingRecursiveComparison()
.ignoringFields("id", "activationCode", "createDate")
.isEqualTo(expectedUserAccount);
但我实际上正在寻找的是通过对某些字段进行以下特殊检查来断言对象是否相等:
id
值的 Long
?activationCode
值的 String
?createDate
值的 Date
?或者,除了为每个字段编写一个断言之外,没有其他方法吗?
答案 0 :(得分:1)
如果你想验证所有的字段都有一个值你可以使用hasNoNullFieldsOrProperties
,而returns
可以用来细化email
的验证(假设getter是暴露的) :
assertThat(actualUserAccount)
.hasNoNullFieldsOrProperties()
.returns(expectedUserAccount.getEmail(), from(UserAccount::getEmail));
如果你必须强制字段的类型,你可以链接:
.extracting(UserAccount::getId, UserAccount::getEmail, UserAccount::getActivationCode, UserAccount::getCreateDate)
.hasExactlyElementsOfTypes(Long.class, String.class, String.class, Date.class);
如果 getter 不可用,您的原始示例可能是验证 email
值的唯一选项:
assertThat(actualUserAccount)
.usingRecursiveComparison()
.ignoringFields("id", "activationCode", "createDate")
.isEqualTo(expectedUserAccount);
但是您仍然可以使用 extracting(String...)
而不是 extracting(Function...)
来强制执行字段的类型:
assertThat(actualUserAccount)
.extracting("id", "email", "activationCode", "createDate")
.hasExactlyElementsOfTypes(Long.class, String.class, String.class, Date.class);
然而,这些选项不利于重构。
答案 1 :(得分:1)
您可以指定如何将某些字段与 withEqualsForFields 进行比较,以便您可以编写如下内容:
assertThat(actualUserAccount)
.usingRecursiveComparison()
.withEqualsForFields((id1, id2) -> id1 instanceof Long && id2 instanceof Long, "id")
.isEqualTo(expectedUserAccount);
我正在检查两个 ids 字段,因为没有保证 id1
是实际 id 而 id2
是预期 id。
您还可以编写一个像 BiPredicate<A, B> isType(T type)
这样的通用方法,它返回一个双谓词,检查两个参数的类型是否为 T(我建议的签名可能不起作用,但您明白了),这样您就可以编写:>
assertThat(actualUserAccount)
.usingRecursiveComparison()
.withEqualsForFields(isType(Long.class), "id")
.withEqualsForFields(isType(String.class), "activationCode")
.withEqualsForFields(isType(Date.class), "createDate")
.isEqualTo(expectedUserAccount);
这是 isType
的样子(不过我还没有测试过):
<A, B, T extends Class<?>> BiPredicate<A, B> isType(T type) {
return (a, b) -> type.isInstance(a) && type.isInstance(b);
}
话虽如此,我可能不会那样写额外的断言。
供参考:https://assertj.github.io/doc/#assertj-core-recursive-comparison-comparators