Dimitri Kopriwa
Dimitri Kopriwa

Reputation: 14443

Spring MVC returning 406 to controller test

I have the following project tree:

├── app
│   ├── build.gradle
│   └── src
│       ├── main
│       │   ├── java
│       │   │   └── child
│       │   │       └── app
│       │   │           └── Application.java
│       │   └── resources
│       │       └── application-default.yaml
│       └── test
│           └── java
│               └── child
│                   └── app
│                       └── ApplicationTest.java
├── build.gradle
└── childA
    ├── build.gradle
    └── src
        ├── main
        │   └── java
        │       └── child
        │           └── a
        │               ├── CoreConfig.java
        │               ├── PingController.java
        │               └── SpringWebMvcInitializer.java
        └── test
            └── java
            │   └── child
            │       └── a
            │           └── PingControllerTest.java
            └── resources
                └── application-core.yml

I have the following test class :

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { PingController.class, SpringWebMvcInitializer.class }, initializers = ConfigFileApplicationContextInitializer.class)
@WebAppConfiguration
@ActiveProfiles({ "core" })
public class PingControllerTest {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void testPing() throws Exception {
this.mockMvc.perform(get(CoreHttpPathStore.PING)).andDo(print());
this.mockMvc.perform(get(CoreHttpPathStore.PING).accept(MediaType.APPLICATION_JSON_UTF8_VALUE).contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)).andExpect(status().isOk());
    }

}

I have the following PingController.java:

@RestController
public class PingController {

    @RequestMapping(value = CoreHttpPathStore.PING, method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<Map<String, Object>> ping() throws Exception {
        HashMap<String, Object> map = new HashMap<>();
        map.put("message", "Welcome to our API");
        map.put("date", new Date());
        map.put("status", HttpStatus.OK);
        return new ResponseEntity<>(map, HttpStatus.OK);
    }

}

I have the following SpringWebMvcInitializer.java:

@ComponentScan
public class SpringWebMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{ "/" };
    }

}

Expected

I expect test to pass with http code 200.

Result

I get 406 and the following print():

04:29:47.488 [main] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Successfully completed request

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /ping
       Parameters = {}
          Headers = {}

Handler:
             Type = com.kopaxgroup.api.core.controller.PingController

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.web.HttpMediaTypeNotAcceptableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 406
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Question

So here are my questions :

Upvotes: 2

Views: 2328

Answers (3)

sergey
sergey

Reputation: 498

I think the easy way is to create TestApplication class and put it in /childA/test/java/a:

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestApplication {
}

and I think it is better to use the following annotation for tests if you use Spring Boot:

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles({"core"})
public class PingControllerTest {
...
}

Upvotes: 1

Amit K Bist
Amit K Bist

Reputation: 6818

Try doing below steps:

@Configuration
    @EnableWebMvc
    public static class PingControllerTestConfiguration {

        @Bean
        public PingController myController() {
            return new PingController();
        }
    }

and

changing below

@ContextConfiguration(classes = { PingController.class, SpringWebMvcInitializer.class }, initializers = ConfigFileApplicationContextInitializer.class)

to @ContextConfiguration

Upvotes: 0

A.Kiva
A.Kiva

Reputation: 1

You can try adding a content type. this.mockMvc.perform(get(CoreHttpPathStore.PING).accept(MediaType.APPLICATION_JSON)).contentType(MediaType.APPLICATION_JSON))andExpect(status().isOk());

Upvotes: 0

Related Questions