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 的次数。

http://www.baeldung.com/mockito-verify

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