我正在尝试使用JUnit编写单元测试,我想使用AssertsEqual测试一个函数,其中我有两个JsonObject列表。以下是我的实际和预期的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 :(得分: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));
}
}
好的,如果您不能使用JSON Unit,您可以尝试散列要比较的JSON列表的内容,对哈希值进行排序,然后比较哈希列表。以下是使用Jackson,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());
}
答案 1 :(得分: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);