Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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 MockMvc+;Hamcrest:浮点数的集合不一致_Java_Unit Testing_Hamcrest_Mockmvc - Fatal编程技术网

Java MockMvc+;Hamcrest:浮点数的集合不一致

Java MockMvc+;Hamcrest:浮点数的集合不一致,java,unit-testing,hamcrest,mockmvc,Java,Unit Testing,Hamcrest,Mockmvc,我想实现一个测试,检查我的浮点变量过滤器是否工作正常。我发送过滤器,并期望集合的值仅低于定义的值 final Double orderPrice = 0.0; this.mockMvc.perform(post(SEARCH_ROUTE) .contentType(contentType) .content(json(buildSearchDtoOnFilter( new FilterDto() {{

我想实现一个测试,检查我的浮点变量过滤器是否工作正常。我发送过滤器,并期望集合的值仅低于定义的值

    final Double orderPrice = 0.0;

    this.mockMvc.perform(post(SEARCH_ROUTE)
        .contentType(contentType)
        .content(json(buildSearchDtoOnFilter(
            new FilterDto() {{
                setFieldName("orderPrice");
                setFilterType(FilterType.LESS);
                setFilterValue(orderPrice.toString());
            }}))))
        .andExpect(status().isOk())
        .andExpect(content().contentType(contentType))

        .andExpect(jsonPath("$.orders", not(empty())))
        .andExpect(jsonPath("$.orders.[*].orderPrice", everyItem(lessThan(orderPrice))));
当执行最后一行检查时,我最终得到了异常

java.lang.ClassCastException:java.lang.Double不能转换为java.math.BigDecimal

at java.math.BigDecimal.compareTo(BigDecimal.java:220)
at org.hamcrest.number.OrderingComparison.matchesSafely(OrderingComparison.java:33)
at org.hamcrest.number.OrderingComparison.matchesSafely(OrderingComparison.java:12)
at org.hamcrest.TypeSafeMatcher.matches(TypeSafeMatcher.java:65)
at org.hamcrest.core.Every.matchesSafely(Every.java:18)
at org.hamcrest.core.Every.matchesSafely(Every.java:8)
at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12)
at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.java:75)
at org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$value$0(JsonPathResultMatchers.java:87)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at org.company.controllers.api.orders.OrderControllerTests.searchOrdersWithDoubleLessFilter(OrderControllerTests.java:536)
我查看了Hamcrest中的代码,看到json解析器在将json响应从MockMvc转换为实际浮点类型时尝试变得聪明:如果数字少于18位,则使用Double,否则使用BigDecimal。这会导致集合中的项不一致:有些是双精度的,有些是BigDecimal的

有没有一个好的干净的方法来解决这个问题


谢谢。

我通过提供自定义匹配器解决了这个问题,但我自己不喜欢这个解决方案。看起来应该有一种更优雅的方法来解决这个问题

验证调用:

.andExpect(jsonPath("$.orders.[*].orderPrice", everyItem(applyConversion(lessThan(orderPrice), ConverterUtils::toDouble))));
public static <TObj, TConst extends java.lang.Comparable<TConst>> org.hamcrest.Matcher<TObj> applyConversion(org.hamcrest.Matcher<TConst> matcher, Function<TObj, TConst> converter) {
    return new TypeSafeMatcher<TObj>() {

        @Override
        public void describeTo(Description description) {
            matcher.describeTo(description);
        }

        @Override
        protected boolean matchesSafely(TObj item) {
            TConst obj = converter.apply(item);
            return matcher.matches(obj);
        }
    };
}


public static double toDouble(Object obj) {
    if (obj instanceof Number)
        return ((Number)obj).doubleValue();
    else if (obj instanceof String)
        return Double.parseDouble((String)obj);
    else
        throw new UnsupportedOperationException(String.format("Cannot convert %s to double", obj));
}
帮助者:

.andExpect(jsonPath("$.orders.[*].orderPrice", everyItem(applyConversion(lessThan(orderPrice), ConverterUtils::toDouble))));
public static <TObj, TConst extends java.lang.Comparable<TConst>> org.hamcrest.Matcher<TObj> applyConversion(org.hamcrest.Matcher<TConst> matcher, Function<TObj, TConst> converter) {
    return new TypeSafeMatcher<TObj>() {

        @Override
        public void describeTo(Description description) {
            matcher.describeTo(description);
        }

        @Override
        protected boolean matchesSafely(TObj item) {
            TConst obj = converter.apply(item);
            return matcher.matches(obj);
        }
    };
}


public static double toDouble(Object obj) {
    if (obj instanceof Number)
        return ((Number)obj).doubleValue();
    else if (obj instanceof String)
        return Double.parseDouble((String)obj);
    else
        throw new UnsupportedOperationException(String.format("Cannot convert %s to double", obj));
}
public static org.hamcrest.Matcher applyConversion(org.hamcrest.Matcher Matcher,函数转换器){
返回新的TypeSafeMatcher(){
@凌驾
公共无效说明(说明){
匹配器描述(描述);
}
@凌驾
受保护的布尔匹配安全(TObj项){
TConst obj=转换器。应用(项目);
返回matcher.matches(obj);
}
};
}
公共静态双toDouble(对象obj){
if(obj实例编号)
return((Number)obj.doubleValue();
else if(字符串的obj实例)
返回Double.parseDouble((String)obj);
其他的
抛出新的UnsupportedOperationException(String.format(“无法将%s转换为double”,obj));
}