Nar*_*csu 3 java testing junit spring mockito
我正在使用如下所示的模拟对象:
@Mock
private RecipeService recipeService
Run Code Online (Sandbox Code Playgroud)
我在测试类中还有以下方法:
@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"));
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我使用mockito的方法来决定当调用指定的方法doThrow时将抛出什么异常。voidsave
我想使用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());
}
Run Code Online (Sandbox Code Playgroud)
上面的方法包含一个try-catch块。当被recipeService.save()调用时,我期望将抛出异常,并由 catch 块处理。但这并没有发生。 相反,会执行其他行。
我缺少什么?
Recipe recipe = new Recipe();
doThrow(Exception.class)
.when(recipeService)
.save(recipe);
Run Code Online (Sandbox Code Playgroud)
仅当将完全相同的实例Recipe传递给 save 方法时,此代码才有效。如果您已经实现了在实例中传递的equalsand/orhashCode方法,Recipe如果预期值1和name可能使其工作。
Recipe recipe = new Recipe();
recipe.setId(1);
recipe.setName("name");
doThrow(Exception.class)
.when(recipeService)
.save(recipe);
Run Code Online (Sandbox Code Playgroud)
然而,由于您可能想测试错误情况,因此总是抛出异常可能更容易。为此,请使用any()匹配器。
doThrow(Exception.class)
.when(recipeService)
.save(any(Recipe.class);
Run Code Online (Sandbox Code Playgroud)
现在,在调用 save 时,无论传入什么,Recipe都会抛出异常。