Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MockMvc HttpMediaTypeNotSupportedException: Content type 'application/json' not supported

I receive the following exception:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported

    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.readWithMessageConverters(HandlerMethodInvoker.java:653)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestBody(HandlerMethodInvoker.java:612)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:361)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:175)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:65)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:167)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)

My test looks like the following:

public class AvailabilityControllerTest extends BaseTest {   
    @Test
    public void createAvailability() throws Exception {
        final String createAvailabilityEndPoint = "/api/v4/companies/123/availabilities";
        final String responseName = "availabilityResponseDTO";

        AvailabilityDTO availabilityDTO = new AvailabilityDTO();

        MvcResult mvcResult = mockMvc.perform(
                MockMvcRequestBuilders.post(createAvailabilityEndPoint)
                        .contentType(MediaType.APPLICATION_JSON_VALUE)
                        .accept(MediaType.APPLICATION_JSON_VALUE)
                        .content(new ObjectMapper().writeValueAsString(availabilityDTO)))
                .andExpect(MockMvcResultMatchers.status().isCreated())
                .andReturn();
    }

With BaseTest as:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
@AutoConfigureMockMvc
public class BaseTest {

    @Autowired
    protected MockMvc mockMvc;

}

TestConfiguration looks like this:

@Configuration
@ComponentScan(
        basePackages = "com.app",
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = App.class)
        }
)
public class TestConfiguration {

    @Bean
    public ErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes();
    }
}

AvailabilityController looks like this:

@RestController
@RequestMapping("/api/v4/companies")
public class AvailabilityController {

    public static final String ACCEPT_APP_JSON = "Accept=" + AcceptableMediaType.APPLICATION_JSON;

    @Autowired
    private AvailabilityFacade availabilityFacade;

@RequestMapping(value = "/{companyId}/employees/{employeeId}/availabilities", method = RequestMethod.GET)
    public List<AvailabilityEventResponseDTO> getUserAvailabilities(@PathVariable String companyId,
                                                                    @PathVariable String employeeId) {
        return availabilityFacade.getUserAvailabilities(employeeId);
    }

    @RequestMapping(value = "/{companyId}/availabilities", method = RequestMethod.POST, headers = ACCEPT_APP_JSON, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<AvailabilityResponseDTO> createAvailability(@PathVariable String companyId,
                                                                      @Valid @RequestBody AvailabilityDTO availabilityDTO) {
        return new ResponseEntity<>(
                availabilityFacade.createAvailability(companyId, availabilityDTO),
                HttpStatus.CREATED
        );
    }
}

Basically the GET request works with MockMvc but the POST does not and returns this HttpMediaTypeNotSupportedException. I have tried to add and remove headers for accept and content type in both the request and the controller and this does not seem to work.

This issue seems to be related to Spring integration test with mockmvc throws org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported but removing the excludeFilters in the TestConfiguration in this case does not allow the context to be interpreted by Spring. Also, I am not sure what Karl R means by "including a serverruntime on my classpath".

Any help is appreciated.

like image 618
dinamix Avatar asked Jun 14 '17 20:06

dinamix


2 Answers

I think you should add @EnableWebMvc to your TestConfiguration.

@Configuration
@ComponentScan(
     basePackages = "com.app",
    excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, 
              classes = App.class)
    }
)
@EnableWebMvc
public class TestConfiguration {
like image 58
walv Avatar answered Nov 17 '22 20:11

walv


In my case the problem was i didn't set contentType, so setting that to JSON type solved the problem for me.

...
.contentType(MediaType.APPLICATION_JSON)
...
like image 27
Harsh Gundecha Avatar answered Nov 17 '22 19:11

Harsh Gundecha