首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将两个相同的json列表按不同的顺序与对象和对象中的字段进行比较

将两个相同的json列表按不同的顺序与对象和对象中的字段进行比较
EN

Stack Overflow用户
提问于 2017-07-26 14:08:04
回答 2查看 3.3K关注 0票数 2

我试图用JUnit编写一个单元测试,我想用AssertsEqual测试一个函数,其中我有两个JsonObjects列表。下面是我的实际和预期的json字符串。

代码语言:javascript
运行
复制
String jsonOutput = [ {
                       id: 1,
                       name: abc,
                       age: 23
                      },
                      {
                       id: 2,
                       name: efg,
                       age: 26
                      },
                      {
                       id: 3,
                       name: rst,
                       age: 26
                      }
     ]


   String jsonExpected = [ {
                            id: 2,
                            name: efg,
                            age: 26
                           },
                           {  
                            id: 1,
                            age: 23,
                            name: abc
                           },
                           {
                            id: 3,
                            name: rst,
                            age: 26
                           }
             ]

在上面的示例中,可以看到对象顺序对期望的字符串发生了更改,各个字段的顺序在各个对象中也发生了变化。

请在下面找到我的测试用例:

代码语言:javascript
运行
复制
   @Test
public void testApply() {
    Command command = new Command();
    Logger logger = LoggerFactory.getLogger(Command.class.getName());
    command.set(logger, new JsonObject());
    command.apply(Buffer.buffer(TestConstants.ALL_GAPS));
    Object eventList = command.apply(Buffer.buffer(TestConstants.OCCUPIED_GAPS)); // returns a list of json objects
    List<JsonObject> expectedList = createExpectedEventList(TestConstants.EVENT_LIST);
    Assert.assertEquals(expectedList, eventList);
}

private List<JsonObject> createExpectedEventList(String eventListString) {
    JsonArray eventArray = new JsonArray(eventListString);
    List<JsonObject> eventList = new ArrayList<>();
    for (Object obj : eventArray) {
        eventList.add((JsonObject) obj);
    }
    return eventList;
}


    Assert.assertEquals(expectedList, eventList);

即使提供了相同的字符串,更改顺序,上述函数也返回false。如果字符串的内容是相同的,不管顺序如何,我希望这个函数返回为true。

EN

回答 2

Stack Overflow用户

发布于 2017-07-26 14:18:42

你查过JSONUnit了吗?

https://github.com/lukas-krecan/JsonUnit

它的描述是:

JsonUnit是一个在单元测试中简化JSON比较的库。

如果您正在使用Maven,您可以创建一个类似于此的项目:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fernandes</groupId>
    <artifactId>jsonunit.test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.8.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.8</version>
        </dependency>

        <dependency>
            <groupId>net.javacrumbs.json-unit</groupId>
            <artifactId>json-unit</artifactId>
            <version>1.25.0</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.0.0-M4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

然后您可以在这里编写一个类似于此的JUnit测试:

代码语言:javascript
运行
复制
package com.fernandes.jsonunit.test;

import org.junit.jupiter.api.Test;

import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
import static net.javacrumbs.jsonunit.JsonAssert.when;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;

/**
 * Created by Gil on 26/07/2017.
 */
public class ArraysTest {

    @Test
    void checkArrays() {
        String array1 = "{\"test\":[4,1,2,3]}";
        String array2 = "{\"test\":[1,2,3,4]}";
        assertJsonEquals(array1, array2, when(IGNORING_ARRAY_ORDER));
    }
}

好的,如果不能使用JSON,可以尝试散列要比较的JSON列表的内容,对散列进行排序,然后比较哈希列表。下面是一个使用Jackson、JUnit 5和Java8的快速示例:

代码语言:javascript
运行
复制
@Test
@DisplayName("When arrays equal, but in different order - match")
void checkArraysManual() throws IOException {
    String array1 = "[{\n" +
            "\"id\": 1,\n" +
            "\"name\": \"abc\",\n" +
            "\"age\": 23\n" +
            "},\n" +
            "{\n" +
            "\"id\": 2,\n" +
            "\"name\": \"efg\",\n" +
            "\"age\": 26\n" +
            "},\n" +
            "{\n" +
            "\"id\": 3,\n" +
            "\"name\": \"rst\",\n" +
            "\"age\": 26\n" +
            "}]";

    String array2 = "[{\n" +
            "\"id\": 2,\n" +
            "\"name\": \"efg\",\n" +
            "\"age\": 26\n" +
            "},\n" +
            "{\n" +
            "\"id\": 1,\n" +
            "\"name\": \"abc\",\n" +
            "\"age\": 23\n" +
            "},\n" +
            "{\n" +
            "\"id\": 3,\n" +
            "\"name\": \"rst\",\n" +
            "\"age\": 26\n" +
            "}]";

    ObjectMapper mapper = new ObjectMapper();
    JsonNode root1 = mapper.readTree(array1);
    JsonNode root2 = mapper.readTree(array2);
    ArrayNode array1Node = (ArrayNode) root1;
    ArrayNode array2Node = (ArrayNode) root2;
    assertThat(compareArrayNodes(array1Node, array2Node), is(true));
}

private boolean compareArrayNodes(ArrayNode array1Node, ArrayNode array2Node) {
    if(array1Node.size() != array2Node.size()) {
        return false;
    }
    List<Integer> hashList1 = hashArrayNode(array1Node);
    List<Integer> hashList2 = hashArrayNode(array2Node);
    return hashList1.equals(hashList2);
}

private List<Integer> hashArrayNode(ArrayNode array1Node) {
    Iterable<JsonNode> supplier = array1Node::elements;
    return StreamSupport.stream(supplier.spliterator(), false)
            .map(Objects::hashCode).sorted()
            .collect(Collectors.toList());
}
票数 4
EN

Stack Overflow用户

发布于 2017-07-26 14:13:37

我有两种选择:

将它们全部放入一个Set中,并比较这些集合:

代码语言:javascript
运行
复制
Set<Foo> a = new HashSet<>(first);
Set<Foo> b = new HashSet<>(second);
assertEquals(a, b);

如果您的列表中包含重复项,则此操作将无效。

或者,只需在比较之前对列表进行排序。任何任意的排序都会工作,只要它是一致的。

代码语言:javascript
运行
复制
List<Foo> a = Collections.sort(new ArrayList<>(first));
List<Foo> b = Collections.sort(new ArrayList<>(second));
assertEquals(a, b);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45329377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档