在EasyMock中,当我们想要记录一个没有像bookService.save();
这样的返回类型的方法的期望时,我们只是在重放之前调用该方法。
我们如何使用Mockito执行此操作,Mockito的replay()
相当于什么?
我的测试控制器是
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addBookPost(@ModelAttribute("book") Book book, HttpServletRequest request, Model model) {
bookService.save(book);
MultipartFile bookImage = book.getBookImage();
try {
byte[] bytes = bookImage.getBytes();
String name = book.getId() + ".png";
BufferedOutputStream stream = new BufferedOutputStream(
new FileOutputStream(new File("src/main/resources/static/image/book/" + name)));
stream.write(bytes);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
return "redirect:bookList";
}
这是我的测试
@Test
public void addBookClicked() throws Exception {
Mockito.verify(bookService).save(book);
mockMvc.perform(get("/book/add").with(user("admin").password("admin").roles("USER","ADMIN"))
.accept(MediaType.TEXT_HTML)
.contentType(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(model().attributeExists("book"))
.andExpect(view().name("addBook"))
.andReturn();
}
但这是错的。我该如何验证通话?
答案 0 :(得分:3)
Mockito没有重播模式。
从this page比较两个框架(重点是我的):
使用Mockito只能将使用Mockito模拟只能做2件事 - 验证或存根。 Stubbing在执行之前进行,然后验证。
replay
+ verify
与Easymock的操作替换为verify
。实际上,在调用后端之前调用Mockito.verify()
。所以它只会失败
你通过混合一些东西来使用EasyMock方法:你用Mockito replay()
替换了EasyMock verify()
。
但如上所述,replay()
不是必需的,而且在Mockito中不存在
所以根据时间顺序做一些事情:调用必须调用mock的方法,然后用Mockito.verify()
断言模拟被有效地调用。
你应该写:
@Test
public void addBookClicked() throws Exception {
mockMvc.perform(get("/book/add").with(user("admin").password("admin").roles("USER","ADMIN"))
.accept(MediaType.TEXT_HTML)
.contentType(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(model().attributeExists("book"))
.andExpect(view().name("addBook"))
.andReturn();
Mockito.verify(bookService).save(book);
}
答案 1 :(得分:2)
两个框架都很相似,但有点不同。
EasyMock希望(默认情况下)对所有内容的期望,然后将验证所有内容。
Mockito将记录发生的事情并让一切通过。就像EasyMock模拟一样,niceMock会这样做。在此过程中,您将获得许多NullPointerExceptions
无空方法,并添加缺少的期望。最后,您可以验证您确实希望确保发生的呼叫。由于这种架构,您不需要进入重放模式。
因此,使用EasyMock,代码将如下所示:
@Test
public void addBookClicked() throws Exception {
bookService.save(book); // no expect or expectLastCall needed
replay(bookService);
mockMvc.perform(get("/book/add").with(user("admin").password("admin").roles("USER","ADMIN"))
.accept(MediaType.TEXT_HTML)
.contentType(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(model().attributeExists("book"))
.andExpect(view().name("addBook"))
.andReturn();
verify(bookService);
}
和Mockito
@Test
public void addBookClicked() throws Exception {
mockMvc.perform(get("/book/add").with(user("admin").password("admin").roles("USER","ADMIN"))
.accept(MediaType.TEXT_HTML)
.contentType(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(model().attributeExists("book"))
.andExpect(view().name("addBook"))
.andReturn();
Mockito.verify(bookService).save(book);
}
请注意,在此示例中,Mockito的语法较短。但情况并非总是如此。例如,假设你save()
方法返回一个已使用的id,你也想确保调用该方法。您最终会重复调用save()
:
@Test
public void addBookClicked() throws Exception {
Mockito.when(bookService.save(book)).thenReturn(1L); // return the id
mockMvc.perform(get("/book/add").with(user("admin").password("admin").roles("USER","ADMIN"))
.accept(MediaType.TEXT_HTML)
.contentType(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(model().attributeExists("book"))
.andExpect(view().name("addBook"))
.andReturn();
Mockito.verify(bookService).save(book);
}
答案 2 :(得分:1)