比较来自JSON的double值的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: IsCloseTo
,但是像这样使用它:
.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
上执行的,而不是在double值上执行的。
你正确地给了一个Matcher<Double>
。 Spring使用Jayway来解析JSON,你的JSON路径将被评估为一个Integer
对象。 匹配将失败,因为Integer
和Double
总是不相等。
因此,您需要将您的Matcher
更改is((int) miles)
。
如果您不控制JSON,并且distanceInMiles
可能会改变,那么这会产生更多问题。 Jayway将解析"4"
作为Integer
但它会将"4.0"
解析为Double
精度。 在这种情况下,您必须通过扩展TypeSafeMatcher
来实现您自己的Matcher
,该Matcher
可处理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;
}
}
它通过将它们的double值与一个已知的double值进行比较来匹配任何Number
。
我发现默认情况下比较为float,所以请尝试如下所示:
.body("field_with_double_value",is(100.0f));
链接地址: http://www.djcxy.com/p/30771.html
上一篇: Hamcrest matcher comparing double value from JSON
下一篇: How to minimize the delay in loading the Font Awesome icons?