Я использую JUnit4 с Spring Web MVC Test, и у меня есть тестовый класс для контроллера.
Контроллер обрабатывает запрос POST к «/test» с содержимым тела JSON. Я протестировал этот метод вручную с помощью Postman и получил ответ 400 Bad Request, как и ожидалось, поскольку свойство «имя» пусто.
POST /Server/test HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
{
"name": ""
}
Однако, когда я отправляю тот же запрос на свой контроллер через свой тестовый класс, я получаю ошибку 415 (неподдерживаемый тип носителя), хотя запрос тот же.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class MyControllerTest {
@Configuration
public static class MyControllerTestConfiguration {
@Bean
public MyController myController() {
return new MyController();
}
}
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void shouldReturnBadRequest_IfBodyIsEmpty() throws Exception {
// Works fine
mockMvc.perform(post("/test"))
.andExpect(status().isBadRequest());
}
@Test
public void shouldReturnBadRequest_IfInvalidFields() throws Exception {
MyDTO dto = new MyDTO();
dto.setName("");
// Jackson object mapper
ObjectMapper mapper = new ObjectMapper();
// TEST FAIL: Gets 415 error
mockMvc.perform(
post("/test")
.content(mapper.writeValueAsString(dto))
.characterEncoding("UTF-8")
.contentType(MediaType.APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isBadRequest());
}
}
А вот и MyController.
@RestController
@EnableWebMvc
public class MyController {
@RequestMapping(value = "/test", method = RequestMethod.POST)
public void init(@javax.validation.Valid @RequestBody MyDTO dto) {
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public void validationError(MethodArgumentNotValidException ex) {
}
}
А вот и MyDTO.
@lombok.Data
public class MyDTO {
private String name;
}
У меня также есть Джексон в моих зависимостях.
Вот как выглядит запрос тестового класса, когда он выводится на консоль:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /test
Parameters = {}
Headers = {Content-Type=[application/json;charset=UTF-8]}
Body = {"name":""}
Session Attrs = {}
Handler:
Type = controller.MyController
Method = public void controller.MyController.init(dto.MyDTO)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = org.springframework.web.HttpMediaTypeNotSupportedException
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 415
Error message = null
Headers = {Accept=[application/octet-stream, text/plain, application/xml, text/xml, application/x-www-form-urlencoded, application/*+xml, multipart/form-data, */*]}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
В любом случае, почему я получаю эту ошибку? Запрос выглядит совершенно нормально для меня. Любая помощь приветствуется. Спасибо.
.characterEncoding("UTF-8")
? - person Aleh Maksimovich   schedule 09.10.2017MockHttpServletResponse
Headers = {Accept=[application/octet-stream, ...]}
не содержитapplication/json
. Возможно, у вас нет библиотеки JSON, поддерживаемой Jackson или Spring, в пути к тестовому классу (зависимость во время выполнения?). Spring будет специально искать HttpMessageConverter, связанный с типом mime, для выполнения преобразования. Spring boot автоматически настраивает MappingJackson2MessageConverter, если Джексон находится на пути к классам. - person Aleh Maksimovich   schedule 09.10.2017ObjectMapper
- это объект из пакета привязки данных Джексона, и он присутствует вMyControllerTest.java
, и тест выполняется без ошибок компиляции. Означает ли это, что он находится в пути к классам? - person the duck wizard   schedule 10.10.2017MappingJackson2MessageConverter
не зарегистрированы, но с информацией в вашем вопросе я не могу сказать, почему. - person Aleh Maksimovich   schedule 10.10.2017