Home > OS >  spring mock mvc perform post request body is missing : error 400
spring mock mvc perform post request body is missing : error 400

Time:01-21

I try to mock a mvc request for testing end to end my controller in spring.

The post request needs a request body but I get an error 400 telling me that required request body is missing even though I see its body using MockMvcResultsHandler print.

project architecture :

  • src
    • main
    • test
      • applications.properties
      • controllers
      • services

So here's my application.properties

spring.datasource.url=jdbc:h2:mem:tesdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=*****
spring.datasource.password=*****
spring.jpa.show-sql = true

Here's my test

@SpringBootTest
@AutoConfigureMockMvc
public class IntegrationTest {
    protected User mockUser;
  
    protected List<User> allUsers;

    @Autowired
    private MockMvc mvc;

    @Autowired
    private WebApplicationContext webApplicationContext;

    @BeforeEach
    public void setUp() {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
    }
    
    @Test
    void testGetAllUsers() throws Exception {
        this.mvc.perform(post("/api/users")
        .accept(MediaType.APPLICATION_JSON)
        .contentType(MediaType.APPLICATION_JSON)
        .characterEncoding("utf-8")     
        .content("{\"name\":\"name\"}"))
        .andDo(print())
        .andExpect(status().isCreated());
   }
}

My @RestController

    @PostMapping(path = "/users")
    public @ResponseBody ResponseEntity<User> addNewUser(
        @RequestBody String name        
    ) {
        return userService.createUser(name);
    }

and my user @Service

public ResponseEntity<User> createUser(String name) {
        User user = new User();
        user.setName(name);
        userRepository.save(user);

And when I try to launch my test I get in my debug console

DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<java.lang.String> ....addNewType(java.lang.String,java.lang.Boolean)]

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/users
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=utf-8", Accept:"application/json", Content-Length:"32"]
             Body = {"name":"concat","unicity":true}
    Session Attrs = {}

and response is :

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

get methods seems to work when I use the same architecture, body seems to be present in the console but servelt doesn't seem to see/understand the request body.

CodePudding user response:

Good Day!

Need to check:

  • API URL
  • Need to run spring application so test method able to call API URL.

CodePudding user response:

Try Creating a explicit json and then pass in body, also in your controller, you are expecting a single string name, try getting that from the json. eg:

@Test
void testGetAllUsers() throws Exception {
    JSONObject json = new JSONObject();
    json.put("name", "john");
    this.mvc.perform(post("/api/users")
    .accept(MediaType.APPLICATION_JSON)
    .contentType(MediaType.APPLICATION_JSON)
    .characterEncoding("utf-8")     
    .content(json.toString())
    .andDo(print())
    .andExpect(status().isCreated()); }

And in your controller you can try something like this

@PostMapping(path = "/users")
public @ResponseBody ResponseEntity<User> addNewUser(
    @RequestBody String name        
) {
    JSONObject json = new JSONObject(name);
    String userName = json.getString("name");
    return userService.createUser(userName);
}
  •  Tags:  
  • Related