Home > Back-end >  Spring boot patch request on controller with Map parameter. Test with mockmvc
Spring boot patch request on controller with Map parameter. Test with mockmvc

Time:04-12

I'm trying to test a 'patch request' from my CompanyController that has a Map and Id as a parameters. I expected get a http status 200, but I get a http status 400. Can someone explain to me what I'm doing wrong? thank you

CompanyController (some parts of the code are omitted):

@RestController
public class CompanyController {

    @Autowired
    private CompanyService companyService;

    @PatchMapping("companies/{id}")
    public ResponseEntity<CompanyDTO> patchUpdateCompany(@PathVariable Integer id,
                                                         @RequestBody Map<String, Object> updates) throws JsonMappingException {

        Optional<CompanyDTO> optionalCompanyDTO = this.companyService.patchUpdateCompany(updates, id);

        return ResponseEntity.ok(optionalCompanyDTO.get());
    }

}

CompanyControllerTest (some parts of the code are omitted)

@WebMvcTest(CompanyController.class)
public class CompanyControllerTest {

    @MockBean
    private CompanyService companyService;

    @Autowired
    private MockMvc mockMvc;

    private static List<CompanyDTO> companyDTOList;

    @BeforeAll
    public static void beforeAll(){
        companyDTOList = new ArrayList<>();
        CompanyDTO companyDTO1 = CompanyDTO.builder().id(1).name("xavi").build();
        CompanyDTO companyDTO2 = CompanyDTO.builder().id(2).name("marteta").build();
        companyDTOList.add(companyDTO1);
        companyDTOList.add(companyDTO2);
    }

    @Test
    void givenMapAndIdWhenPatchUpdateCompanyThenReturnHttpStatusOk() throws Exception {
        Mockito.when(this.companyService.getCompanyById(1)).thenReturn(Optional.of(companyDTOList.get(0)));

        MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
        parameters.add("name", "xavi2");

        this.mockMvc.perform(patch("/companies/1")
            .contentType(MediaType.APPLICATION_JSON)
            .params(requestParams))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name", Matchers.is("xavi2")));

    }
}

CodePudding user response:

Your problem is here

this.mockMvc.perform(patch("/companies/1")
            .contentType(MediaType.APPLICATION_JSON)
            .params(requestParams))  <---------------------
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name", Matchers.is("xavi2")));

    }

You pass the data as request parameters. But in your API you have @RequestBody meaning it expects to get the data in http request body and not as request parameters.

This is why you face 400 error meaning Bad Request which is caused by Spring having matched the URL path and also the http method type but something additional which was in the signature of API method was not provided in your request.

So you should use the .content(requestParams) method to set the content you want in the body of the request which you will send

Related documentation

Otherwise your API should have used @RequestParam instead of @RequestBody to receive the input as request parameters as previously sent from test.

  • Related