I am trying to test a post method called saveProduct in my springboot application. It takes params like product, bindingResult, model, multipartFile, redirectAttributes. The product has an attribute photo.
The issue is I am getting an http status is 400 when it is supposed to be 200. I looked at the several online documentation on how to test post api but I still cant figure it out. This is one of the documentation I was looking at on how to test a post multipart uploading springboot application. https://spring.io/guides/gs/uploading-files/
Controller class (method)
@PostMapping("/showNewProductForm")
public String addAProduct(@Valid @ModelAttribute("saved") Product product,
BindingResult bindingResult,
Model model,
@RequestParam("image") MultipartFile file,
RedirectAttributes redirectAttributes) {
return productService
.saveProduct(product, bindingResult, model, file, redirectAttributes);
}
Service class (method)
public String saveProduct(Product product,
BindingResult bindingResult,
Model model,
MultipartFile file,
RedirectAttributes redirectAttributes) {
Optional<Product> productByName = productRepository.findProductByName(product.getName());
if (bindingResult.hasErrors()) {
return "add-new-product"; // For binding error, you always return to the form instead of the get API
} else if (productByName.isPresent()) {
redirectAttributes.addFlashAttribute("message",
product.getName() + " already exists, please enter a different name");
return "redirect:/showNewProductForm";
}
boolean checkImageUploadStatus = addingImageLogic(product, file);
if (!checkImageUploadStatus) {
redirectAttributes.addFlashAttribute("message", "Please enter an image for " + product.getName());
return "redirect:/showNewProductForm";
}
productRepository.save(product);
model.addAttribute("saved", product);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + product.getName() + "!");
return "redirect:/showNewProductForm";
}
Test class
@WebMvcTest(ProductController.class)
class ProductControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private ProductService productService;
@Test
void addAProduct() throws Exception {
/*
* Product parameters are
* product (name, category, description, photo)
*/
Product product = new Product();
product.setName("Test Run");
product.setCategory("Dairy");
product.setDescription("Lorem 24");
Model model = mock(Model.class);
BindingResult bindingResult = mock(BindingResult.class);
RedirectAttributes redirectAttributes = mock(RedirectAttributes.class);
// When
MockMultipartFile mockMultipartFile = new MockMultipartFile(
"image",
"green-bean.jpg",
"image/png, image/jpg, image/jpeg",
"random img".getBytes()
);
when(productService
.saveProduct(product, bindingResult, model, mockMultipartFile, redirectAttributes))
.thenReturn(String.valueOf(product));
// then
this.mockMvc
.perform(multipart("/showNewProductForm")
.file(mockMultipartFile))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name", is("Test Run")));
then(this.productService)
.should()
.saveProduct(product, bindingResult, model, mockMultipartFile, redirectAttributes);
}
}
The error message
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [showNewProductForm], template might not exist or might not be accessible by any of the configured Template Resolvers
