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
. Вот учебник по официальной документации, который показывает, как это сделать.