Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hamcrest matcher比较JSON中的双精度值_Java_Json_Spring_Spring Test_Hamcrest - Fatal编程技术网

Java Hamcrest matcher比较JSON中的双精度值

Java Hamcrest matcher比较JSON中的双精度值,java,json,spring,spring-test,hamcrest,Java,Json,Spring,Spring Test,Hamcrest,我使用HamcrestCoreMatcher类作为spring测试集成测试的一部分。我的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.mockM

我使用Hamcrest
CoreMatcher
类作为
spring测试
集成测试的一部分。我的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)))
我的集成测试如下所示:

{"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)
导致一个奇怪的错误:

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)
java.lang.AssertionError:JSON路径“$.data[0].distanceInMiles”
应为:在的范围内的数值
但是:是java.lang.Integer()
位于org.hamcrest.matcherasert.assertThat(matcherasert.java:20)

我希望避免包含某种错误-我希望返回值正好是
4
,我只是不关心包含多少个尾随零。

问题是匹配是在
整数上执行的,而不是在双值上执行的

您正确地给出了一个
匹配器
。Spring在引擎盖下使用Jayway解析JSON,您的JSON路径将作为
Integer
对象进行计算。匹配将失败,因为
整数
双精度
始终不相等

因此,您需要将
匹配器
更改为
is((int)英里)

如果您不控制正在获取的JSON,并且
distanceInMiles
可能会更改,那么问题就更大了。Jayway将
“4”
解析为
整数
,但将
“4.0”
解析为
双精度
。在这种情况下,您必须实现自己的
Matcher
,它通过扩展
TypeSafeMatcher
来处理
Integer
Double
对象。这将是一个简单的实现:

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;
    }

}
class NumberMatcher扩展了TypeSafeMatcher{
私人双重价值;
公用号码表(双值){
这个值=值;
}
@凌驾
公共无效说明(说明){
//一些描述
}
@凌驾
受保护的布尔匹配安全(数字项){
返回项。doubleValue()==值;
}
}

它通过将其双精度值与已知的双精度值进行比较来匹配任何
数字。

我发现默认情况下比较为float,所以请尝试以下操作:

.body("field_with_double_value",is(100.0f));

问题是,
double
值用于创建模型对象,然后作为JSON响应的一部分对其进行检查,因此我希望重用相同的变量,以避免重复键入它两次。我将更新我的代码块进行演示。顺便问一下,你在使用Java 8吗?是的,我在使用Java 8。不幸的是,
closeTo
也给了我一些非常奇怪的问题-问题更新了。@CraigOtis是的,这是因为它仍然不是预期的类型。我忘了Hamcrest是做打字检查的。您必须实现自己的matcher。如何使用double而不是float进行这种比较?