JSON数组比较自定义中出错(sky screamer)

JSON数组比较自定义中出错(sky screamer),json,java-8,customization,junit5,assertj,Json,Java 8,Customization,Junit5,Assertj,我有以下两个JSON要比较 预期的json: [ { "id": 1, "code": 1, "createdOn": null, "lastModifiedOn": null }, { "id": 2, "code": 1, "createdOn": null, "lastModifiedOn": null } ] 实际json [ { "id": 1, "code": 1, "c

我有以下两个JSON要比较

预期的json:

 [
  {
    "id": 1,
    "code": 1,
    "createdOn": null,
    "lastModifiedOn": null

  },
  {
    "id": 2,
    "code": 1,
    "createdOn": null,
    "lastModifiedOn": null
  }
]
实际json

[
  {
    "id": 1,
    "code": 1,
    "createdOn": "2019-12-31",
    "lastModifiedOn": "2019-12-31",
  },
  {
    "id": 2,
    "code": 1,
    "createdOn": "2019-12-31",
    "lastModifiedOn": "2019-12-31",
  }
]
尝试使用以下代码忽略两个节点进行比较

JSONAssert.assertEquals(actualjson, expectedjson,
new CustomComparator(JSONCompareMode.STRICT, 
    new Customization("createdOn", (o1, o2) -> {
        return true;
    }), 
    new Customization("lastModifiedOn", (o1, o2) -> {
        return true;
    })
)));
但它失败了,下面是一个例外

java.lang.AssertionError: [0].createdOn
Expected: null
     got: 2019-12-31
 ; [0].lastModifiedOn
Expected: null
     got: 2019-12-31
 ; [1].createdOn
Expected: null
     got: 2019-12-31
 ; [1].lastModifiedOn
Expected: null
     got: 2019-12-31
如何通过跳过createdon和lastmodifiedon节点将json值数组与自定义对象进行比较

<groupId>org.assertj</groupId>
<version>2.2.1</version>
org.assertj
2.2.1

方法1:解析JSON并重新创建两个不带日期属性的对象JSON


方法2:解析JSON并在每个要比较的属性上放置一个断言。

尝试一下它允许您选择哪些应该有帮助。

由于SkyScreamer在github中指出了一个公开问题,我找到了临时解决方案,并认为这对其他人会有帮助

解决方案

ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    List<DomainObject> actualDomainObj = mapper.readValue(actualJson, new TypeReference<List<DomainObject>>() {
    });
    List<DomainObject> expectedDomainObj = mapper.readValue(expectedJson, new TypeReference<List<DomainObject>>() {
    });
    assertDomainObjResults(actualDomainObj.get(0), expectedDomainObj.get(0));


private void assertDomainObjResults(DomainObject actual, DomainObject expected) {
    softAssertions.assertThat(actual.getId()).isEqualTo(expected.getId());
    softAssertions.assertThat(actual.getLastModifiedOn()).isEqualTo(LocalDate.now());
    softAssertions.assertThat(actual.getCreatedOn()).isEqualTo(LocalDate.now());
}
ObjectMapper mapper=new ObjectMapper();
registerModule(新的JavaTimeModule());
列出actualDomainObj=mapper.readValue(actualJson,newtypereference(){
});
List expectedDomainObj=mapper.readValue(expectedJson,new TypeReference(){
});
assertDomainObjResults(actualDomainObj.get(0),expectedDomainObj.get(0));
私有无效资产DomainObjResults(实际域对象,预期域对象){
assertThat(实际的.getId()).isEqualTo(预期的.getId());
assertThat(actual.getLastModifiedOn()).isEqualTo(LocalDate.now());
assertThat(actual.getCreatedOn()).isEqualTo(LocalDate.now());
}

如果有人认为答案有用,请接受它。

我最近创建了一个自定义比较器,允许您在“预期”JSON中使用正则表达式:

public class ExtendedJsonComparator extends DefaultComparator {
    public ExtendedJsonComparator(JSONCompareMode mode) {
        super(mode);
    }

    @Override
    public void compareValues(String prefix, Object expectedValue, Object actualValue, JSONCompareResult result) throws JSONException {
        String expected = expectedValue.toString().trim();
        String actual = actualValue.toString();
        if(expected.startsWith("${") && expected.endsWith("}")) {
            String regex = expected.substring(2, expected.length() - 1);
            if(!actual.matches(regex)) {
                result.fail(prefix, expected, actual);
            }
        } else {
            super.compareValues(prefix, expectedValue, actualValue, result);
        }
    }
}
对于“预期”,您可以执行以下操作,或者创建与日期格式匹配的正则表达式(如果您正在测试):

[
  {
    "id": 1,
    "code": 1,
    "createdOn": "${.*}",
    "lastModifiedOn": "${.*}"

  },
  {
    "id": 2,
    "code": 1,
    "createdOn": "${.*}",
    "lastModifiedOn": "${.*}"
  }
]

将JSONCompareMode.STRICT更改为JSONCompareMode.LENIENT。@KunalVohra LENIENT将完全忽略节点,在将来的响应契约中添加任何额外节点都不会使具有此属性的测试用例失败。