java - 如何在 JUnit 测试中执行自定义 JSON 比较?

标签 java json junit

我有名为 Info 的 JSON 对象,它只有字符串,如下所示:

{
  "prop1":      "value1",
  "prop2":      "value1",
  "timestamp":  "2018-02-28T05:30:10.100Z",
  "prop4":      "value4",
  "prop_N":     "I have a total of 10 properties."
}

我想将它们与预期的 JSON 对象进行比较。

为此,我将预期和实际的 JSON 转换为 Java 对象/POJO。我预期的 JSON 可以在 4 个属性中的任何一个中包含 null。如果任何预期的 JSON 字段为空,那么我希望我的代码不比较这些字段。如果它们不为空,则使用 String.equals() 进行比较,但有一个异常(exception):对于始终为 UTC 的时间戳,我们必须忽略秒和毫秒.

比较的结果将在 JUnit 断言方法中使用,以检查实际接收到的 JSON 是否与预期的 JSON 匹配。

我已经实现了如下所示的代码。但是,有两个问题:

  1. 它不会告诉您哪些字段不匹配(它只是返回 true/false)
  2. 由于存在多个 if block ,因此非常难看。

有人可以建议如何解决这些问题吗?

public boolean matchesInfo(Info givenInfo) throws Exception {

    if (this.getProp1() != null) {
        boolean prop1Matching = this.getProp1().equals(givenInfo.getProp1());
        if (prop1Matching == false){return false;}
    }

    // More if blocks like this. Very long and ugly.

    // For timestamp comparison, call a custom function to strip seconds, milliseconds.
}

最佳答案

您可以使用 JsonUnit 而不是将 JSON 反序列化为对象以方便比较以便在测试用例中进行有意义的“JSON 比较”。

下面有一些示例解决了您问题中提出的要点...显示有意义的响应(即命名不匹配的字段/值),忽略空/不存在字段。还有更多详细信息in the docs ,包括使用自定义匹配器来处理此要求:“对于始终为 UTC 的时间戳,我们必须忽略秒和毫秒。”。

@Test
public void canAssertJsonEquality() {
    String expected = "{\n" +
            "  \"prop1\": \"value1\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";
    String actual = "{\n" +
            "  \"prop1\": \"value1\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";

    JsonAssert.assertJsonEquals(expected, actual);
}

@Test
public void canAssertJsonEqualityRegardlessOfPropertyOrder() {
    String expected = "{\n" +
            "  \"prop1\": \"value1\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";
    String actual = "{\n" +
            "  \"prop2\": \"value1\",\n" +
            "  \"prop1\": \"value1\"\n" +
            "}";

    JsonAssert.assertJsonEquals(expected, actual);
}

@Test
public void canIgnoreFieldsWhichAreInActualButNotInExpected() {
    String expected = "{\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";
    String actual = "{\n" +
            "  \"prop1\": \"value1\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";

    JsonAssert.assertJsonEquals(expected, actual, JsonAssert.when(Option.IGNORING_EXTRA_FIELDS));
} 

// fails with ...
//      Different keys found in node "", expected: <[prop1, prop2]> but was: <[prop2]>. Missing: "prop1"
@Test
public void willFailIfActualIsMissingAProperty() {
    String expected = "{\n" +
            "  \"prop1\": \"value1\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";
    String actual = "{\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";

    JsonAssert.assertJsonEquals(expected, actual);
}

// fails with ...
//      Different value found in node "prop1", expected: <"value1"> but was: <"value2">.
@Test
public void willFailIfActualHasAnIncorrectValue() {
    String expected = "{\n" +
            "  \"prop1\": \"value1\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";
    String actual = "{\n" +
            "  \"prop1\": \"value2\",\n" +
            "  \"prop2\": \"value1\"\n" +
            "}";

    JsonAssert.assertJsonEquals(expected, actual);
} 

关于java - 如何在 JUnit 测试中执行自定义 JSON 比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49246074/

相关文章:

java - 无法从 C 代码对 Java getter 进行 JNI 调用

javascript - 通过 AJAX 将多个 JSON 对象传递到 ASP.Net PageMethod

javascript - 从 twitch 获取 json API。当我不在线时出现 Uncaught TypeError 。 JSON 更改

java - 如何在不重叠先前数据的情况下编写 JSON 文件

java - 多个 java 实例 -Xms -Xmx

java - maven-dependency-plugin 没有使用 destFileName?

java - 如何模拟作为参数传递给方法的异常

java - 为什么我的 DataPoints 方法被多次调用?

java - Powermockito 私有(private)方法模拟 NullPointerException。调用私有(private)方法

java - gradle generate jar具有资源文件,但运行jar会导致无效资源