Mockito 和 EasyMock
Mockito and EasyMock
在 EasyMock 中,当我们想要记录对没有 return 类型的方法的期望时,例如 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();
}
但这是错误的。我应该如何验证来电?
verify(bookService).save(book)
验证可以设置为按顺序进行验证,and/or 应调用 mock 的次数。
Mockito 没有回放模式。
来自this page比较两个框架(重点是我的):
There only 2 things you can do with Mockito mocks - verify or stub.
Stubbing goes before execution and verification afterwards.
使用 Easymock 的 replay
+ verify
操作只能用 Mockito 替换为 verify
。
但是,对于 Mockito,必须在 之后 执行验证。
实际上您在调用后端之前调用了 Mockito.verify()
。所以只能失败。
你通过混合一些东西使用了 EasyMock 方式:你用 Mockito verify()
.
替换了 EasyMock replay()
但如前所述,replay()
不是必需的,Mockito 中也不存在。
因此,只需根据时间顺序做事:调用必须调用模拟的方法,然后用 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);
}
两个框架相似但略有不同。
EasyMock 将(默认情况下)期望所有内容,然后验证所有内容。
Mockito 将只记录发生的事情并忽略所有内容。就像 EasyMock 模拟 niceMock 会做的那样。在此过程中,您将获得许多 NullPointerExceptions
for none void 方法并添加缺失的期望。最后,您可以验证您真正想要确保发生的呼叫。由于这种架构,您无需进入重播模式。
因此,使用 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()
方法 returns 一个已使用的 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);
}
在 EasyMock 中,当我们想要记录对没有 return 类型的方法的期望时,例如 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();
}
但这是错误的。我应该如何验证来电?
verify(bookService).save(book)
验证可以设置为按顺序进行验证,and/or 应调用 mock 的次数。
Mockito 没有回放模式。
来自this page比较两个框架(重点是我的):
使用 Easymock 的There only 2 things you can do with Mockito mocks - verify or stub. Stubbing goes before execution and verification afterwards.
replay
+ verify
操作只能用 Mockito 替换为 verify
。
但是,对于 Mockito,必须在 之后 执行验证。
实际上您在调用后端之前调用了 Mockito.verify()
。所以只能失败。
你通过混合一些东西使用了 EasyMock 方式:你用 Mockito verify()
.
替换了 EasyMock replay()
但如前所述,replay()
不是必需的,Mockito 中也不存在。
因此,只需根据时间顺序做事:调用必须调用模拟的方法,然后用 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);
}
两个框架相似但略有不同。
EasyMock 将(默认情况下)期望所有内容,然后验证所有内容。
Mockito 将只记录发生的事情并忽略所有内容。就像 EasyMock 模拟 niceMock 会做的那样。在此过程中,您将获得许多 NullPointerExceptions
for none void 方法并添加缺失的期望。最后,您可以验证您真正想要确保发生的呼叫。由于这种架构,您无需进入重播模式。
因此,使用 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()
方法 returns 一个已使用的 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);
}