2017-07-26 62 views
1

我想用JUnit編寫一個單元測試,我想用AssertsEqual來測試一個函數,其中有兩個JsonObjects列表。以下是我的實際和預期的json字符串。比較兩個相同的json列表與對象內的對象和對象的順序不同

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 
          } 
      ] 

在上面的例子,它可以看出,對象順序被改變爲期望的字符串和各個字段的順序的單個對象內也被改變。

請在下面找到我的測試情況:即使提供相同的字符串改變順序

@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,如果字符串的內容是相同的,而不管順序如何。

+0

*你嘗試過什麼到目前爲止*向我們展示一些代碼,請 – Lino

+0

單元測試的情況下加入。 – Salam

+0

雖然我明白你在這裏要做什麼,但我擔心你錯過了一條非常關鍵的信息。有序不同的Json數組是不相等的。 –

回答

1

兩個選項了我的頭頂部:

扔他們都爲Set,並比較集:

Set<Foo> a = new HashSet<>(first); 
Set<Foo> b = new HashSet<>(second); 
assertEquals(a, b); 

如果你的列表中包含重複這將無法正常工作。


或者,只是在比較之前對列表進行排序。任何排序都可以工作,只要一致。

List<Foo> a = Collections.sort(new ArrayList<>(first)); 
List<Foo> b = Collections.sort(new ArrayList<>(second)); 
assertEquals(a, b); 
+0

單元測試案例增加了,你可以看看嗎? – Salam

+0

由於'Foo'(JsonObject)不具有可比性,因此無法使用Collections.sort。 – Salam

+0

啊。這是一個痛苦。首先將它們轉換爲字符串。 – Michael

3

您是否檢查過JSONUnit?

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

它的描述是:

JsonUnit是簡化了單元測試JSON比較的庫。

如果您正在使用Maven,你可以創建這樣一個項目:

<?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測試:

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)); 
    } 
} 

OK,如果你無法使用JSON單元,您可以嘗試散列要比較的JSON列表的內容,對散列進行排序,然後比較散列列表。下面是一個簡單的例子使用傑克遜的JUnit 5和Java 8:

@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()); 
} 
+0

謝謝,我遇到了這個庫,但我需要一個解決方案而不添加額外的依賴項。 – Salam

+0

這有點恥辱。在我看來,你的要求非常適合這個圖書館。它可以處理列表比較,「不管命令如何」,就像你所要求的。 –

+0

我完全同意你的解決方案,但我只是有限地添加額外的依賴關係:) – Salam