Статьи

JUnit Hamcrest Matcher для JSON

В этом посте показано, как можно написать тесты JUnit для проверки соответствия объекта строке JSON. Это важно, если вы внедряете службы REST и хотите проверить, дает ли ваша служба ожидаемый ответ JSON.

Полезная библиотека для сравнения объектов JSON — это JSONassert . Сначала вы должны преобразовать ваш Java-объект в строку JSON (например, с помощью Джексона ), а затем сравнить ее с ожидаемой строкой JSON с помощью JSONassert. (Вы также можете преобразовать свой Java-объект в JSONObject но я считаю, что гораздо проще преобразовать его в строку.)

В следующем фрагменте показано, как можно сравнить объект (в данном случае List ) с его представлением JSON с помощью JSONassert.

1
2
3
4
5
6
7
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);

Чтобы упростить написание таких модульных тестов, я написал Hamcrest Matcher под названием IsEqualJSON для сравнения объектов JSON. Он по-прежнему использует JSONassert, но позволяет вам выразить ваши тесты более свободно.

Следующий код показывает, как используется IsEqualJSON :

1
2
3
4
5
6
7
8
9
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 ):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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));
  }
}
Опубликовано на Java Code Geeks с разрешения Фахда Шарифа, партнера нашей программы JCG . Смотрите оригинальную статью здесь: JUnit Hamcrest Matcher for JSON

Мнения, высказанные участниками Java Code Geeks, являются их собственными.