2017-10-09 4 views
2

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.

+0

Können Sie mir sagen, ob der Test 415 zurückgibt, wenn Sie '.characterEncoding (" UTF-8 ")'? –

+0

@ AlehMaksimovich Ja, es tut es immer noch. –

+0

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. –

Antwort

3

Ich habe das Problem gelöst, indem ich meine innere statische MyControllerTestConfiguration-Klasse mit @EnableWebMvc annotierte.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration 
@WebAppConfiguration 
public class MyControllerTest { 

    @Configuration 
    @EnableWebMvc // <------------ added this 
    public static class MyControllerTestConfiguration { 

     @Bean 
     public SetupController setupController() { 
      return new MyController(); 
     } 

    } 
Verwandte Themen