是 Java 杰克逊 ObjectWriter.ObjectWriter.writeValueAsString(obj);稳定的?
Is Java jackson ObjectWriter.ObjectWriter.writeValueAsString(obj); stable?
我目前正在使用 TestNg 编写测试用例。我使用 PodamFactory 填充对象。我有以下测试用例结构。
@Test
public void testIt(){
ARespObject resp = PodamFactory.manufacturePojo(ARespObject.class);
String responseXml = new JaxbStringTransformer().transform(resp);
// a new object with all the same data
ARespObject respActual = responder.getObj(responseXml);
Assert.assertTrue(TestUtils.areEqual(respActual , resp));
}
public static <T extends Object> boolean areEqual(T sourceObj, T target) {
if (sourceObj == null && target == null) {
return true;
}
if (sourceObj == target) {
return true;
}
if (sourceObj.getClass() != target.getClass()) {
return false;
}
if (sourceObj != null && target != null) {
return stringifyObject(sourceObj).equals(stringifyObject(target));
}
return false;
}
public static String stringifyObject(Object obj) {
String result = "";
ObjectWriter ow = new JaxbJacksonObjectMapper().writer().withDefaultPrettyPrinter();
try {
result = ow.writeValueAsString(obj);
} catch (JsonGenerationException e1) {
LOG.error(e1);
} catch (JsonMappingException e1) {
LOG.error("JsonMappingException: " + e1);
} catch (IOException e1) {
LOG.error("IOException: " + e1);
}
return result;
}
我需要知道 writeValueAsString(obj) 是否总是为两个对象(即它的输出将是稳定的)和以下对象提供相同的结构
stringifyObject(sourceObj).equals(stringifyObject(target));
是一张有效的支票。我担心它是否会在 ARespObject 中给我不同的变量排序。
我建议不要使用对象的字符串表示来测试相等性。您应该改用要测试的对象的 .equals
方法。
与其将对象格式化为字符串进行比较,不如将它们转换为 "tree model"(JsonNode 实现)。 ObjectNode 实现 equals/hashCode/toString 等以合理地模仿 JSON 等价,因此它将忽略属性的顺序,例如
ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.convertValue(obj, JsonNode.class);
(通常您实际上会得到一个 ObjectNode,但您可以只使用 JsonNode 接口)
树模型 类 还将对 toString() 输出执行简单的 JSON 格式化,因此 "expected" 和 "actual" 打印输出应该是可读的(尽管不像漂亮的打印机)
我目前正在使用 TestNg 编写测试用例。我使用 PodamFactory 填充对象。我有以下测试用例结构。
@Test
public void testIt(){
ARespObject resp = PodamFactory.manufacturePojo(ARespObject.class);
String responseXml = new JaxbStringTransformer().transform(resp);
// a new object with all the same data
ARespObject respActual = responder.getObj(responseXml);
Assert.assertTrue(TestUtils.areEqual(respActual , resp));
}
public static <T extends Object> boolean areEqual(T sourceObj, T target) {
if (sourceObj == null && target == null) {
return true;
}
if (sourceObj == target) {
return true;
}
if (sourceObj.getClass() != target.getClass()) {
return false;
}
if (sourceObj != null && target != null) {
return stringifyObject(sourceObj).equals(stringifyObject(target));
}
return false;
}
public static String stringifyObject(Object obj) {
String result = "";
ObjectWriter ow = new JaxbJacksonObjectMapper().writer().withDefaultPrettyPrinter();
try {
result = ow.writeValueAsString(obj);
} catch (JsonGenerationException e1) {
LOG.error(e1);
} catch (JsonMappingException e1) {
LOG.error("JsonMappingException: " + e1);
} catch (IOException e1) {
LOG.error("IOException: " + e1);
}
return result;
}
我需要知道 writeValueAsString(obj) 是否总是为两个对象(即它的输出将是稳定的)和以下对象提供相同的结构
stringifyObject(sourceObj).equals(stringifyObject(target));
是一张有效的支票。我担心它是否会在 ARespObject 中给我不同的变量排序。
我建议不要使用对象的字符串表示来测试相等性。您应该改用要测试的对象的 .equals
方法。
与其将对象格式化为字符串进行比较,不如将它们转换为 "tree model"(JsonNode 实现)。 ObjectNode 实现 equals/hashCode/toString 等以合理地模仿 JSON 等价,因此它将忽略属性的顺序,例如
ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.convertValue(obj, JsonNode.class);
(通常您实际上会得到一个 ObjectNode,但您可以只使用 JsonNode 接口)
树模型 类 还将对 toString() 输出执行简单的 JSON 格式化,因此 "expected" 和 "actual" 打印输出应该是可读的(尽管不像漂亮的打印机)