vendredi 21 juin 2019

Adding a @valid object to multipart request in Spring Mockito Testing

I'm trying to test a request method in Spring in which is a multipart form request. This request needs a @valid object to pass a redirection and can have an optional multipart image. However, I'm unable to attach a @valid object in testing therefore causing errors.

I've tried mocking the object by using Mockito.when(), Mockito.verify() doNothing().when(), doAnswer.when() ect but none to help solve the problem.

The method that needs testing

@RequestMapping(path = "/recipes/add", method = RequestMethod.POST)
public String persistRecipe(@Valid Recipe recipe, BindingResult result, @RequestParam("image") MultipartFile photo, RedirectAttributes redirectAttributes) {
    if (result.hasErrors()) {
        result.getAllErrors().forEach(System.out::println);
        redirectAttributes.addFlashAttribute("recipe", recipe);
        redirectAttributes.addFlashAttribute("flash",
                new FlashMessage("I think you missed something. Try again!", FlashMessage.Status.FAILURE));
        return "redirect:/recipes/add";
    }

    User user = getUser();
    recipe.setOwner(user);
    user.addFavorite(recipe);
    recipeService.save(recipe, photo);
    userService.save(user);
    redirectAttributes.addFlashAttribute("flash", new FlashMessage("The recipe has successfully been created", FlashMessage.Status.SUCCESS));

    return "redirect:/recipes"

The test method currently

@Test
@WithUserDetails(value = "daniel")
public void createNewRecipeRedirects() throws Exception {
    User user = userBuilder();
    MockMultipartFile photo = new MockMultipartFile("image", "food.jpeg",
            "image/jpeg", "dummy content file".getBytes());

    when(userService.findByUsername("daniel")).thenReturn(user);
    doNothing().when(recipeService).save(any(Recipe.class), any(MultipartFile.class));
    doNothing().when(userService).save(any(User.class));

    mockMvc.perform(multipart("/recipes/add")
                    .file(photo)).andDo(print())
            .andExpect(redirectedUrl("/recipes"))
            .andExpect(status().is3xxRedirection());

}

I expect the test to pass by effectively adding a new recipe to the database and then redirecting from /recipes/add uri to /recipes uri. Instead, I get these errors:

Field error in object 'recipe' on field 'description': rejected value 
[null]; 
Field error in object 'recipe' on field 'category': rejected value [null]; 
Field error in object 'recipe' on field 'name': rejected value [null]; 

Effectively, the form is not reading a @valid recipe object hence instead of a successful redirect its a failure redirecting back to /recipes/add.

If anyone can help me solve this problem that would be great, thanks.

Aucun commentaire:

Enregistrer un commentaire