Образец заявления на этот вопрос здесь: https://github.com/olemerdy-fa/webmvctestКомбинат @WebMcvTest с @PathVariable аннотированных контроллеров в Spring загрузки 1,41
Я развернув новый проект с использованием Spring бутсу 1.4.1. Я стараюсь использовать новые возможности в этой великолепной структуре, особенно способность (полностью) тестировать «срезы» моего приложения.
Я сейчас борется с функцией @WebMvcTest
при использовании на @Controller
, объявляя аннотированный метод @PathVariable
.
Действительно, @WebMvcTest
должен загружать один контроллер и средство тестирования MockMvc, не предоставляя ничего другого. Используя @MockBean
, до сих пор довольно легко предоставить издевательствам в качестве зависимостей для ввода внутри этого контроллера.
Но как насчет аннотированного параметра @PathVariable
, тип которого является, скажем, объектом JPA, чей конвертер обычно регистрируется данными Spring?
Пример проект присоединился к этому вопрос содержит несколько образцов:
MyEntity
является простой JPA сущности иMyEntityRepository
его Spring Данные, связанные хранилищамиWebmvctest1Controller
имеетload
метод извлечения идентификатора из пути и называет себя методомMyEntityRepository.findOne(id)
Webmvctest1ControllerUnitTest
проверяет этот контроллер на насмешкуMyEntityRepository
и все идет хорошоWebmvctest2Controller
имеетload
метод с@PathVariable
аннотированныйMyEntity
который смотрел вверх Спринг данных зарегистрированы конвертер@RestController public class Webmvctest2Controller { @RequestMapping("load2/{id}") public MyEntity load2(@PathVariable("id") MyEntity myEntity) { return myEntity; } }
Webmvctest2ControllerUnitTest
то, где я застрял, так как я не знаю, как обеспечить макет лица в качестве параметр, при этом используяMockMvc
@RunWith(SpringRunner.class) @WebMvcTest(Webmvctest2Controller.class) public class Webmvctest2ControllerUnitTest { @Autowired private MockMvc mvc; @Test public void load2() throws Exception { // How do I mock converter to PathVariable here? mvc.perform(get("/load2/123").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().json("{id:123,name:'My Entity 123'}")); } }
Это терпит неудачу с org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
исключением
2016-10-25 14:27:55.699 WARN 20753 --- [ main] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to convert request element: org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type [java.lang.String] to required type [com.stackoverflow.MyEntity]; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.stackoverflow.MyEntity]: no matching editors or conversion strategy found
MockHttpServletRequest:
HTTP Method = GET
Request URI = /load2/123
Parameters = {}
Headers = {Accept=[application/json]}
Handler:
Type = com.stackoverflow.Webmvctest2Controller
Method = public com.stackoverflow.MyEntity com.stackoverflow.Webmvctest2Controller.load2(com.stackoverflow.MyEntity)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 500
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.375 sec <<< FAILURE! - in com.stackoverflow.Webmvctest2ControllerUnitTest
load2(com.stackoverflow.Webmvctest2ControllerUnitTest) Time elapsed: 0.015 sec <<< FAILURE!
java.lang.AssertionError: Status expected:<200> but was:<500>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at com.stackoverflow.Webmvctest2ControllerUnitTest.load2(Webmvctest2ControllerUnitTest.java:28)
WebmvctestApplicationTests
показывает, что все в порядке, в обоих случаях, когда приложение полностью бутстрапированная
Любая идея, как я могу держать мои @PathVariable
параметры сущности, пока еще только тестирование мой веб-фрагмент с @WebMvcTest
? Спасибо :)
_ «a @WebMvcTest должен загружать один контроллер и средство тестирования MockMvc, не предоставляя ничего другого». _ Вы в основном ответили на свой вопрос, поэтому я не уверен, какой ответ вы ожидаете. Вам не нужно '@ WebMvcTest' использовать' MockMvc'. Что еще более важно: запрос не имеет тела, поэтому почему метод должен ожидать, что объект как параметр? – zeroflagL
Образец, приведенный здесь, просто показывает, что происходит. В коде реального мира метод не просто перенаправляет объект, а может его модифицировать, запрашивать подзадачу, использовать несколько методов конвертируемых. На самом деле, если загрузка объекта в сигнатуре запроса вызывает беспокойство, вопрос остается в силе с любым типом, конвертер которого не зарегистрирован весной (скажем: Joda Money). –
Здесь мы можем протестировать наш контроллер только при загрузке всего. Я ищу решение, поддерживающее дух срезов (http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html), который загружает только несколько сервисов слой, который мы тестируем (здесь только веб-часть, а не данные или сервисные уровни). Что мы можем сделать, чтобы загружать веб-контроллер и издеваться над всеми его зависимостями, не изменяя исходный код контроллера (я хочу сохранить богатые типы @PathVariable и позволить Spring обрабатывать преобразования)? –