Java Hamcrest matcher比较JSON中的双精度值
我使用HamcrestJava 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
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进行这种比较?