使用 Mockito 的 doThrow 方法时不会引发异常



我正在使用如下所示的模拟对象:

@Mock
private RecipeService recipeService

我在测试类中也有以下方法:

    @Test
    public void testAddRecipeWithNonUniqueName() throws Exception {
        Recipe recipe = new Recipe();
        doThrow(Exception.class)
                .when(recipeService)
                .save(recipe);
        mockMvc.perform(post("/recipes/add-recipe")
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .param("id", "1")
                .param("name", "recipe1"))
                .andExpect(status().is3xxRedirection())
                .andExpect(view().name("redirect:/recipes/add"));
    }

如您所见,我正在使用 mockito 的 doThrow 方法来决定调用名为 savevoid方法时将引发的异常。

我想使用 MockMvc 对象发出 POST 请求。因此,标有 /recipes/add-recipe 终结点的方法将在我的一个控制器类中调用。以下代码片段详细介绍了该方法:

    @RequestMapping(value = "/recipes/add-recipe", method = RequestMethod.POST)
    public String addRecipe(@Valid Recipe recipe, BindingResult result, RedirectAttributes redirectAttributes,
                            @AuthenticationPrincipal User user){
       String response = validateFormValues(recipe, redirectAttributes, result,
               "redirect:/recipes/add");
       if(!response.isEmpty())return response;
        recipe.setUser(user);
        try {
            recipeService.save(recipe);
        }catch(Exception e){
            redirectAttributes.addFlashAttribute("uniqueConstraintError",
                    String.format("The name "%s" is already taken by another recipe. " +
                                    "Please try again!",
                            recipe.getName()));
            return "redirect:/recipes/add";
        }
        setUserForIngredientsAndSteps(recipe);
        redirectAttributes.addFlashAttribute("flash",
                new FlashMessage("The recipe has been added successfully!", FlashMessage.Status.SUCCESS));
        return String.format("redirect:/recipes/%s/detail", recipe.getId());
    }

上面的方法包含一个 try-catch 块。当调用recipeService.save()时,我预计会抛出异常,并由 catch 块处理。但这不会发生。相反,将执行其他行。

我错过了什么?

Recipe recipe = new Recipe();
doThrow(Exception.class)
        .when(recipeService)
        .save(recipe);

仅当将完全相同的 Recipe 实例传递给 save 方法时,此代码才有效。如果已实现传入Recipe实例的 equals 和/或hashCode方法,则预期值1name可能会使其正常工作。

Recipe recipe = new Recipe();
recipe.setId(1);
recipe.setName("name");
doThrow(Exception.class)
        .when(recipeService)
        .save(recipe);

但是,由于您可能想要测试错误情况,因此始终抛出异常可能更容易。为此,请使用any()匹配器。

doThrow(Exception.class)
        .when(recipeService)
        .save(any(Recipe.class);

现在,在调用 save 时,无论传入的Recipe如何,都会引发异常。

仅当您保存之前创建的特定配方时,才会触发您正在调用的doTrhow()方法。

你需要告诉莫奇托扔任何食谱

Mockito.doThrow(Exception.class)
            .when(recipeService)
            .save(Mockito.any(Recipe.class));

相关内容

  • 没有找到相关文章

最新更新