使用 AssertJ 比较具有某些字段的“特殊”断言的两个对象

Rob*_*uch 7 assertj

鉴于以下课程...

public class UserAccount {
  private Long id;
  private String email;
  private String activationCode;
  private Date createDate;
}
Run Code Online (Sandbox Code Playgroud)

...我需要使用 AssertJ 将实际对象与预期对象进行比较。然而, fieldsid和具有动态值,我无法将activationCodecreateDate硬编码到断言中。

所以下面的断言将会失败:
assertThat(actualUserAccount).isEqualTo(expectedUserAccount);

然后我发现以下内容会忽略某些字段:

assertThat(actualUserAccount)
        .usingRecursiveComparison()
        .ignoringFields("id", "activationCode", "createDate")
        .isEqualTo(expectedUserAccount);
Run Code Online (Sandbox Code Playgroud)

但我实际上正在寻找的是通过对某些字段进行以下特殊检查来断言对象是否相等:

  • 有没有id任何Long价值?
  • 有没有activationCode任何String价值?
  • 有没有createDate任何Date价值?

或者除了为每个字段编写一个断言之外没有其他方法吗?

Joe*_*ola 12

您可以指定如何将某些字段与withEqualsForFields进行比较,以便您可以编写如下内容:

assertThat(actualUserAccount)
        .usingRecursiveComparison()
        .withEqualsForFields((id1, id2) -> id1 instanceof Long && id2 instanceof Long, "id")
        .isEqualTo(expectedUserAccount);
Run Code Online (Sandbox Code Playgroud)

我正在检查两个 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);
Run Code Online (Sandbox Code Playgroud)

看起来像这样isType(不过我还没有测试过):

<A, B, T extends Class<?>> BiPredicate<A, B> isType(T type) {
    return (a, b) -> type.isInstance(a) && type.isInstance(b);
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,我可能不会那样写额外的断言。

供参考:https ://assertj.github.io/doc/#assertj-core-recursive-comparison-comparators