Mocking Spring MVC BindingResult при использовании аннотаций

Я переношу контроллер Spring MVC для использования новых аннотаций стиля и хочу unit test метод контроллера, который проверяет объект команды (см. простой пример ниже).

 @RequestMapping(method = RequestMethod.POST)
public String doThing(Command command, BindingResult result,
                    HttpServletRequest request, HttpServletResponse response,
                    Map<String, Object> model){ 
    ThingValidator validator = new ThingValidator();
    validator.validate(command, result);
... other logic here
    }

Моя проблема заключается в том, что я должен вызвать метод контроллера в моем unit test и предоставить макетные значения, чтобы удовлетворить свою подпись, чтобы правильно использовать код, и я не могу понять, как издеваться над BindingResult.

В старом контроллере стиля подпись просто взяла HttpServletRequest и HttpServletResponse, которые были легко издевательски, но из-за гибкости нового стиля аннотации нужно пройти намного больше через подпись.

Как можно издеваться над Spring BindingResult для использования в unit test??

Ответы

Ответ 1

BindingResult - это интерфейс, поэтому не можете ли вы просто передать одну из реализаций Springs этого интерфейса?

Я не использую аннотации в моем MVC-коде Spring, но когда я хочу проверить метод проверки правильности проверки, я просто передаю экземпляр BindException, а затем использую значения, которые он возвращает в assertEquals и т.д.

Ответ 2

Вы также можете использовать что-то вроде Mockito, чтобы создать макет BindingResult и передать его вашему методу контроллера, то есть

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verifyZeroInteractions;

@Test
public void createDoesNotCreateAnythingWhenTheBindingResultHasErrors() {
    // Given
    SomeDomainDTO dto = new SomeDomainDTO();
    ModelAndView mv = new ModelAndView();

    BindingResult result = mock(BindingResult.class);
    when(result.hasErrors()).thenReturn(true);

    // When
    controller.create(dto, result, mv);

    // Then
    verifyZeroInteractions(lockAccessor);
}

Это может дать вам большую гибкость и упростить строительные леса.

Ответ 3

Как уже упоминалось в этом ответе

Spring MVC создает для вас BindingResult для каждого входящего HTTP-запроса.

Таким образом, вы не хотите издеваться над BindingResult.

Вместо прямого вызова методов вы должны либо выполнить реальный http-вызов контроллера, либо выполнить моделирование с использованием MockMvc.perform. Вот учебник по официальной документации, который показывает, как это сделать.