Ich benutze JUnit4 mit Spring Web MVC Test und ich habe Testklasse für einen Controller.Spring 5.0.0 MockMvc: Nicht unterstützter Medientyp, auch mit korrektem MediaType Set
Der Controller behandelt eine POST-Anfrage zum "/ test" mit JSON-Body-Inhalt. Ich habe diese Methode manuell mit Postman getestet und bekomme wie erwartet eine 400 Bad Request-Antwort, da die "name" -Eigenschaft leer ist.
POST /Server/test HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
{
"name": ""
}
Allerdings, wenn ich die gleiche Aufforderung an meinen Controller durch meinen Test-Klasse senden, erhalte ich einen 415 (Unsupported Media Type) Fehler, auch wenn die Anfrage gleich ist.
@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());
}
}
Und hier ist 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) {
}
}
Und hier ist MyDTO.
@lombok.Data
public class MyDTO {
private String name;
}
Ich habe Jackson in meinen Abhängigkeiten ebenso.
Hier ist, was die Anforderung des Testklasse aussieht, wenn es auf der Konsole ausgegeben hat:
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 = []
Anyways, warum sollte ich diesen Fehler bekommen? Die Anfrage sieht für mich vollkommen in Ordnung aus. Jede Hilfe wird geschätzt. Vielen Dank.
Können Sie mir sagen, ob der Test 415 zurückgibt, wenn Sie '.characterEncoding (" UTF-8 ")'? –
@ AlehMaksimovich Ja, es tut es immer noch. –
Es ist verdächtig, dass 'MockHttpServletResponse'' Header = {Accept = [application/octet-stream, ...]} '' nicht 'application/json' enthält. Vielleicht haben Sie keine Jackson oder andere Spring-unterstützte JSON-Bibliothek auf Ihrem Test-Klassenpfad (Laufzeitabhängigkeit?). Spring sucht speziell nach einem HttpMessageConverter, der dem Mime-Typ zugeordnet ist, um die Konvertierung durchzuführen. Spring boot konfiguriert MappingJackson2MessageConverter automatisch, wenn sich jackson im Klassenpfad befindet. –