java - Hamcrest 匹配器比较来自 JSON 的 double 值

标签 java json spring spring-test hamcrest

我使用 Hamcrest CoreMatcher 类作为 spring-test 集成测试的一部分。我的 JSON 看起来像:

{"data":[{"distanceInMiles":4,"id":"f97236ba-f4ef-4...

我的集成测试看起来像:

double miles = 4.0
Activity a = new BasicActivity(miles);
this.activityManager.add(a); // A mock activity manager (in-memory)
...
this.mockMvc.perform(get("/").accept("application/json"))
    .andExpect(jsonPath("$.data[0].distanceInMiles", is(miles)))

但是,断言失败了:

java.lang.AssertionError: JSON path "$.data[0].distanceInMiles"
Expected: is <4.0>
     but: was <4>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)

我知道这里有一个单独的 IsCloseTo 匹配器:http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/number/IsCloseTo.html , 但像这样使用它:

.andExpect(jsonPath("$.data[0].distanceInMiles", closeTo(miles, 0)))

导致一个奇怪的错误:

java.lang.AssertionError: JSON path "$.data[0].distanceInMiles"
Expected: a numeric value within <0.0> of <4.0>
     but: was a java.lang.Integer (<4>)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)

我希望避免包含某种错误 - 我希望返回的值正好是 4,我只是不在乎有多少尾随零包括在内。

最佳答案

问题是匹配是在Integer上执行的s 而不是 double 值。

您正确地给出了 Matcher<Double> . Spring 在底层使用 Jayway 来解析 JSON,您的 JSON 路径将被评估为 Integer。目的。匹配将失败,因为 Integer和一个 Double总是不平等的。

因此,您需要更改 Matcheris((int) miles) .

如果你不控制你得到的 JSON 和 distanceInMiles可能会改变,这更成问题。 Jayway 将解析 "4"作为Integer但它会解析 "4.0"作为Double .在这种情况下,您将必须实现自己的 Matcher处理 IntegerDouble通过扩展对象 TypeSafeMatcher .这将是一个简单的实现:

class NumberMatcher extends TypeSafeMatcher<Number> {

    private double value;

    public NumberMatcher(double value) {
        this.value = value;
    }

    @Override
    public void describeTo(Description description) {
        // some description
    }

    @Override
    protected boolean matchesSafely(Number item) {
        return item.doubleValue() == value;
    }

}

它匹配任何 Number通过将它们的 double 值与已知的 double 值进行比较。

关于java - Hamcrest 匹配器比较来自 JSON 的 double 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34107420/

相关文章:

java - 异常(exception):JTA事务意外回滚(可能是由于超时)

java - Spring 应用程序上下文的计时

java - Android 蓝牙套接字连接使用 AsyncTask 在后台接收数据

java - Android JavaCV - UnsatisfiedLinkError并且找不到 "libopencv_core.so"

java - java中泛型函数的多重扩展

ios - Swift:由于 URLSession.DataTask 递归调用 ViewDidLoad

spring - 使用 Spring Security 集成单点登录

java - 使用 apache IOUtils.copy() 和 setContent() 复制文档内容

Python嵌套json对象被序列化为str

php - 如何使用 laravel5 从数据 mysql 中提取 json 数据作为对象?