java - 使用 Mockito 的 doThrow 方法时不会抛出异常

标签 java spring testing junit mockito

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

@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 请求。因此,将在我的 Controller 类之一中调用标记有 /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 block 。当调用 recipeService.save() 时,我预计会抛出一个异常,并由 catch block 处理。 但这并没有发生。 而是执行其他行。

我错过了什么?

最佳答案

Recipe recipe = new Recipe();

doThrow(Exception.class)
        .when(recipeService)
        .save(recipe);

只有将完全相同的 Recipe 实例传递给保存方法时,此代码才有效。如果您实现了 equals 和/或 hashCode 方法,如果预期值为 1 并且传入 Recipe 实例name 可能会起作用。

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);

现在调用保存时,不管传入的Recipe 都会抛出异常。

关于java - 使用 Mockito 的 doThrow 方法时不会抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54650555/

相关文章:

testing - Isim 未测试测试夹具中的所有位

scala - 如何使用反向路由测试重定向位置?

Angular 5 测试返回错误

java - 调用rest api客户端

java - 我面临这个错误的问题

Java HashMap 内容好像变了没变

java - 如何使用 thymeleaf 递归渲染菜单

java - 如何防止SIGINT信号杀死Java中的子进程

spring - Spring 已弃用的 NoSuchRequestHandlingMethodException 的替代品是什么?

spring - 使用自定义 UserDetails 实现测试 Spring Security 和 MvcMock