MockMvc Integration or Unit testing a POST API that takes parameters like @Valid Object, BindingResult, MultipartFile

Viewed 23

How do I test a post api method that takes the parameters like Multipartfile etc. Based on spring documentation I understand I have to use multipart instead of post for MockMvc, but my response status is 400 instead of 200. (Feel free to use your own example to give me an idea of how to test this).

Test class and method

@Autowired
private MockMvc mockMvc;

@MockBean
private ProductService productService;

@Test
void newProduct() {
        // Given
        Product product = new Product("Test", "Diary", "Lorem 24", "fresh-pepper.jpg");
        product.setId(1L);
        product.setPath("dummy photo path");
        MockMultipartFile multipartFile = new MockMultipartFile("file",
                "fresh-pepper.jpg",
                "image/png, image/jpg, image/jpeg",
                "random image".getBytes());
        //When
        when(productService.saveProduct(product, multipartFile)).thenReturn(product);

        //Then
        try {
            this.mockMvc.perform(multipart("/dummy/api/v1/addNew")
                    .file(multipartFile))
                    .andDo(print())
                    .andExpect(status().isOk());

        } catch (Exception e) {
            e.printStackTrace();
        }

}

Rest api method and NOTE @RequestMapping("/dummy/api/v1")

@PostMapping(path = "/addNew", consumes = {MULTIPART_FORM_DATA_VALUE})
    public ResponseEntity<Product> newProduct(@Valid Product product,
                                              BindingResult bindingResult,
                                              @RequestParam("file") MultipartFile file) {
        if (bindingResult.hasFieldErrors()){
            bindingResult.getFieldErrors().forEach(fieldError -> LOGGER.error("Error " + fieldError.getField()));
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<>(productService.saveProduct(product, file), HttpStatus.OK);
    }
1 Answers

The issue is I did not pass the parameter just like I would if I tested my api using post man. So basically just like this.

@Test
    void newProduct() {
        // Given
        MockMultipartFile multipartFile = new MockMultipartFile("file",
                "fresh-pepper.jpg",
                "image/png, image/jpg, image/jpeg",
                "random image".getBytes());

        //Then
        try {
            this.mockMvc.perform(
                    multipart("/secured/api/v2/addNew")
                            .file(multipartFile)
                            .param("name", "Test")
                            .param("category", "Test")
                            .param("description", "Lorem 23")
                    )
                    .andDo(print())
                    .andExpect(status().isOk());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
Related