MockMvc + Hamcrest: противоречивые коллекции для чисел с плавающей запятой - PullRequest
0 голосов
/ 20 сентября 2018

Я хотел бы реализовать тест, который проверяет, что мой фильтр для переменной с плавающей запятой работает хорошо.Я отправляю фильтр и ожидаю, что коллекция будет иметь значения только ниже определенного значения.

    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ИсключениеMockMvc для фактического типа с плавающей запятой: если число имеет менее 18 цифр, оно использует Double, иначе используется BigDecimal.Что приводит к несовместимым элементам в коллекции: некоторые будут Double, а некоторые - BigDecimal.

Есть ли хороший и чистый способ обойти это?

Спасибо.

1 Ответ

0 голосов
/ 21 сентября 2018

Я работал над этим, предоставляя пользовательское сопоставление, но мне не нравилось это решение.Похоже, должен быть способ решить эту проблему более элегантным способом.

Проверка вызова:

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