【发布时间】:2019-02-12 12:52:41
【问题描述】:
我正在使用如下模拟对象:
@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 方法来决定在调用名为 save 的 void 方法时将引发什么异常。
我想使用 MockMvc 对象发出 POST 请求。因此,标有/recipes/add-recipe 端点的方法将在我的一个控制器类中调用。以下 sn-p 代码详细显示了该方法:
@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实例时才会引发异常。而是使用any()作为匹配器。 -
@M.Deinum 现在我明白了。我的一个简单的错误。但现在我会有一个不同的问题。在这种情况下,
save方法可以采用Recipe或List<Recipe>对象。所以如果我打电话给any(),我会得到“不明确的方法调用”编译错误。这种情况我该怎么办? -
使用
any(Recipe.class)。 -
附带说明,您几乎不应该
catch Exception,当然也不在这里;除了重复项之外,还有许多其他错误条件,您不应一视同仁。
标签: java spring testing junit mockito