Java에서 하위 순서를 무시하는 동등성을 위해 두 개의 JSON 오브젝트 테스트 웹 서비스에서

자식 순서를 무시하고 특히 웹 서비스에서 반환되는 JSON을 단위 테스트하는 두 JSON 객체 비교를 지원하는 JSON 구문 분석 라이브러리를 찾고 있습니다.

주요 JSON 라이브러리가 이것을 지원합니까? org.json 라이브러리는 단순히 참조 비교를 수행합니다.



답변

일반적인 아키텍처 포인트로서, 나는 보통 특정 직렬화 형식에 대한 의존성이 스토리지 / 네트워킹 계층을 넘어서 빠져 나가지 않도록 권고합니다. 따라서 먼저 JSON 표현이 아닌 자체 응용 프로그램 객체 간의 동등성을 테스트하는 것이 좋습니다.

나는 현재 Jackson 의 열렬한 팬이며 ObjectNode.equals () 구현 에 대한 빠른 읽기에서 원하는 멤버쉽 비교를 제안합니다.

public boolean equals(Object o)
{
    if (o == this) return true;
    if (o == null) return false;
    if (o.getClass() != getClass()) {
        return false;
    }
    ObjectNode other = (ObjectNode) o;
    if (other.size() != size()) {
        return false;
    }
    if (_children != null) {
        for (Map.Entry<String, JsonNode> en : _children.entrySet()) {
            String key = en.getKey();
            JsonNode value = en.getValue();

            JsonNode otherValue = other.get(key);

            if (otherValue == null || !otherValue.equals(value)) {
                return false;
            }
        }
    }
    return true;
}

답변

Skyscreamer의 JSONAssert를 사용해보십시오 .

그것의 비 엄격 모드는 덜 취성 수 있도록 두 가지 장점이 있습니다 :

  • 객체 확장 성 (예 : 예상 값이 {id : 1} 인 경우에도 여전히 {id : 1, moredata : ‘x’}를 전달합니다. 합니다.)
  • 느슨한 배열 순서 (예 : [ ‘dog’, ‘cat’] == [ ‘cat’, ‘dog’])

엄격 모드에서는 json-lib의 테스트 클래스와 비슷하게 동작합니다.

테스트는 다음과 같습니다.

@Test
public void testGetFriends() {
    JSONObject data = getRESTData("/friends/367.json");
    String expected = "{friends:[{id:123,name:\"Corby Page\"}"
        + ",{id:456,name:\"Solomon Duskis\"}]}";
    JSONAssert.assertEquals(expected, data, false);
}

JSONAssert.assertEquals의 매개 변수 () 호출하는 expectedJSONString , actualDataString을 하고 isStrict .

결과 메시지는 매우 명확하며 실제로 큰 JSON 객체를 비교할 때 중요합니다.


답변

GSON 사용

JsonParser parser = new JsonParser();
JsonElement o1 = parser.parse("{a : {a : 2}, b : 2}");
JsonElement o2 = parser.parse("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

편집 : GSON v2.8.6 부터 인스턴스 메소드 JsonParser.parse는 더 이상 사용되지 않습니다. 정적 메소드를 사용해야합니다 JsonParser.parseString.

JsonElement o1 = JsonParser.parseString("{a : {a : 2}, b : 2}");
JsonElement o2 = JsonParser.parseString("{b : 2, a : {a : 2}}");
assertEquals(o1, o2);

답변

나는 다음을 할 것이다.

JSONObject obj1 = /*json*/;
JSONObject obj2 = /*json*/;

ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(obj1.toString());
JsonNode tree2 = mapper.readTree(obj2.toString());

return tree1.equals(tree2);

답변

json-lib의 JSONAssert 클래스를 사용해보십시오 .

JSONAssert.assertEquals(
  "{foo: 'bar', baz: 'qux'}",
  JSONObject.fromObject("{foo: 'bar', baz: 'xyzzy'}")
);

제공합니다 :

junit.framework.ComparisonFailure: objects differed at key [baz]; expected:<[qux]> but was:<[xyzzy]>

답변

이 라이브러리를 사용하십시오. https://github.com/lukas-krecan/JsonUnit

치어 리더 :

<dependency>
    <groupId>net.javacrumbs.json-unit</groupId>
    <artifactId>json-unit</artifactId>
    <version>1.5.0</version>
    <scope>test</scope>
</dependency>

IGNORING_ARRAY_ORDER-배열의 순서를 무시

assertJsonEquals("{\"test\":[1,2,3]}",
  "{\"test\":  [3,2,1]}",
  when(IGNORING_ARRAY_ORDER)
);

답변

JUnit을 이미 사용중인 경우 최신 버전은 Hamcrest를 사용합니다. 새로운 매칭기를 구축하기 위해 확장 될 수있는 일반적인 매칭 프레임 워크 (특히 단위 테스트에 유용함)입니다.

hamcrest-jsonJSON을 인식 하는 작은 오픈 소스 라이브러리 가 있습니다. 문서화, 테스트 및 지원이 잘되어 있습니다. 다음은 유용한 링크입니다.

JSON 라이브러리의 객체를 사용하는 예제 코드 org.json.simple:

Assert.assertThat(
    jsonObject1.toJSONString(),
    SameJSONAs.sameJSONAs(jsonObject2.toJSONString()));

선택적으로 (1) “모든 순서”배열을 허용하고 (2) 추가 필드를 무시할 수 있습니다.

Java 용 JSON 라이브러리의 다양한 있기 때문에 ( Jackson, GSON, json-lib, 등)이 유용하다는 것을 hamcrest-json지원하는 JSON 텍스트 (등 java.lang.String), 더글러스 크록 포드의 JSON 라이브러리에서뿐만 아니라 기본적으로 지원하는 객체org.json .

마지막으로 JUnit을 사용하지 않는 경우 어설 션에 Hamcrest를 직접 사용할 수 있습니다. ( 나는 여기에 썼습니다. )