这篇文章展示了如何编写JUnit测试来检查对象是否与JSON字符串匹配。 如果您要实现REST服务并想测试您的服务是否产生了预期的JSON响应,那么这一点很重要。
JSONassert是比较JSON对象的有用库。 首先,您必须将Java对象转换为JSON字符串(例如,使用Jackson ),然后使用JSONassert将其与期望的JSON字符串进行比较。 (您也可以将Java对象转换为JSONObject
但我发现将其转换为字符串要容易得多。)
以下代码段显示了如何使用JSONassert将对象(在这种情况下为List
)与其JSON表示形式进行比较。
import org.skyscreamer.jsonassert.JSONAssert;
import com.fasterxml.jackson.databind.ObjectMapper;
List<String> fruits = Arrays.asList("apple", "banana");
String fruitsJSON = new ObjectMapper().writeValueAsString(fruits);
String expectedFruitsJSON = "[\"apple\", \"banana\"]";
JSONAssert.assertEquals(expectedFruitsJSON, fruitsJSON, true);
为了简化编写这样的单元测试,我编写了一个名为IsEqualJSON
的Hamcrest Matcher,用于比较JSON对象。 它仍然使用JSONassert,但允许您以更流畅的方式表达测试。
以下代码显示了如何使用IsEqualJSON
:
import static org.junit.Assert.*;
import static testutil.IsEqualJSON.*;
assertThat(Arrays.asList("apple", "banana"),
equalToJSON("[\"apple\", \"banana\"]"));
// you can also have your expected JSON read from a file
assertThat(Arrays.asList("apple", "banana"),
equalToJSONInFile("fruits.json"));
这是IsEqualJSON
的代码(也在我的GitHub Repository中提供 ):
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import org.hamcrest.*;
import org.skyscreamer.jsonassert.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* A Matcher for comparing JSON.
* Example usage:
* <pre>
* assertThat(new String[] {"foo", "bar"}, equalToJSON("[\"foo\", \"bar\"]"));
* assertThat(new String[] {"foo", "bar"}, equalToJSONInFile("/tmp/foo.json"));
* </pre>
*/
public class IsEqualJSON extends DiagnosingMatcher<Object> {
private final String expectedJSON;
private JSONCompareMode jsonCompareMode;
public IsEqualJSON(final String expectedJSON) {
this.expectedJSON = expectedJSON;
this.jsonCompareMode = JSONCompareMode.STRICT;
}
@Override
public void describeTo(final Description description) {
description.appendText(expectedJSON);
}
@Override
protected boolean matches(final Object actual,
final Description mismatchDescription) {
final String actualJSON = toJSONString(actual);
final JSONCompareResult result = JSONCompare.compareJSON(expectedJSON,
actualJSON,
jsonCompareMode);
if (!result.passed()) {
mismatchDescription.appendText(result.getMessage());
}
return result.passed();
}
private static String toJSONString(final Object o) {
try {
return o instanceof String ?
(String) o : new ObjectMapper().writeValueAsString(o);
} catch (final JsonProcessingException e) {
throw new RuntimeException(e);
}
}
private static String getFileContents(final Path path) {
try {
return new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
@Factory
public static IsEqualJSON equalToJSON(final String expectedJSON) {
return new IsEqualJSON(expectedJSON);
}
@Factory
public static IsEqualJSON equalToJSONInFile(final Path expectedPath) {
return equalToJSON(getFileContents(expectedPath));
}
@Factory
public static IsEqualJSON equalToJSONInFile(final String expectedFileName) {
return equalToJSONInFile(Paths.get(expectedFileName));
}
}
翻译自: https://www.javacodegeeks.com/2018/03/junit-hamcrest-matcher-for-json.html