是 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" 打印输出应该是可读的(尽管不像漂亮的打印机)