当前位置: 首页 > 知识库问答 >
问题:

在mockito中验证的想法是什么?我应该在什么时候使用它

夏理
2023-03-14

我理解mockito.verify()用于确保使用所需参数调用模拟方法。但我不明白这其中的用意。我经常看到类似这样的测试:

public class UserDAO {
    public long create(User user) {
        //...
    }
}

public class UserService {
    private UserDAO userDAO;

    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public long createUser(User user) {
        return userDAO.create(user);
    }
}

public class UserServiceTest {
    @Test
    public void testCreateUser() {
        UserDAO userDAO = mock(UserDAO.class);
        when(userDAO.create(any(User.class))).thenReturn(anyLong());

        UserService = new UserService(userDAO);
        User user = new User("John Smith");
        userService.createUser(user);

        verify(userDAO).create(user);
    }
}

测试验证在调用UserService的createUser方法时是否调用了UserDAO的create方法。看起来很荒唐。如果我改变了UserService的实现,使它不调用UserDAO的方法,那么即使实现是正确的,测试也会失败。

我承认在某些情况下,可能需要验证方法被调用的次数是准确的,但这种情况并不常见。

很可能我不理解验证的概念,而且它不是mockito特有的特性。你能用简单的话解释一下吗?什么时候用它才真正有意义。

共有2个答案

寿卜鹰
2023-03-14

这个userServiceTest的全部要点是测试它的实现。因此,是的,您确实希望验证是否调用了userDAO接口的create方法。

游勇军
2023-03-14

verify()方法是一种用于白盒测试的工具。但是,您要测试的不是实际实现,而是测试是否将某种消息(方法调用)发送到底层,或者更准确地说,指定在测试代码执行后使用API。

测试通常包括以下步骤:

  • 准备输入(输入参数、环境、(模拟)系统等),
  • 调用代码进行测试
  • 将实际结果(输出参数、对环境的更改)与预期结果(一组假设)进行比较

但是预期的结果不一定是一些输出数据,而是环境的一些变化。但是如果您已经模拟了需要定义的环境,那么环境是如何受到您的代码的影响的,并且对环境(或其他组件)的访问通常是通过API完成的。

让我们以create方法为例。该方法没有返回值,但假设在基础数据层(环境)上创建了数据集。当您已经嘲弄了数据层,当没有存储时,如何验证某些数据是否已存储?因此,在假设除了调用create方法之外,没有其他存储数据的选项(从组件的角度来看)的情况下,可以合理地假设,为了存储数据,必须调用create方法。因此verify(yourComponent).create()证明了代码的执行是正确的。当然,这需要使用某个API的知识(提供create方法),因此这是一种白箱测试。

还有其他的用例:

>

  • 调用数(即传递了10个项,假设添加了10个项:verify(list,times(10)).add(any(item.class))

    捕获参数,即断言发生了某个转换或传递了正确的参数,并且您需要访问该参数

    argumentCaptor captor=argumentCaptor.forClass(expectedType.Class);验证(theApi).apimethod(captor.capture());ExpectedType passedParam=Captor.GetValue();

    验证一个方法没有被调用(即在某些条件下,结合阳性测试)

    验证已调用具有某些参数的方法(=已发送特定消息):验证(subject).method(eq(“param1”),eq(“param2”))

    但所有这些都归结为指定API的使用,以便指定预期将哪些消息发送到另一个组件或html" target="_blank">系统,而不是指定测试中实现的每一行(这将是毫无意义的)。

  •  类似资料:
    • 我想知道什么时候可以有效地使用。我不确定到底有多有用,有三个原因。 (请将start和end视为整数。) > 如果我想要一个数组,,下面的代码要快得多。 我不认为仅仅获取从到的数字是有用的。我可以将

    • 我是一个新的Mockito,遵循这一点,并试图找出验证方法做什么。它似乎是用来确保所选方法被调用一次。我有下面的代码,通过查看代码,我可以发现我调用了addBook方法两次,所以为什么我要使用verify?我的意思是,在任何情况下,都很容易确保一个方法被称为oncem,那么为什么我们要使用verify方法呢?

    • 有没有人遇到过使用场景?由于是默认选项,我看不到你什么时候会使用它。

    • 问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮​​助。但是,在发送流数据时,等待A

    • 问题内容: 在该类中,有两个字符串,和。 有什么不同?我什么时候应该使用另一个? 问题答案: 如果你的意思是和则: 用于在文件路径列表中分隔各个文件路径。考虑在上的环境变量。您使用a分隔文件路径,因此在上将是;。 是或用于拆分到特定文件的路径。例如在上,或

    • 最近,我收到了在代码中使用's的建议,或者在站点上看到了一些使用's的答案--应该是某种容器。但是--我在C++17标准库里找不到类似的东西。 那么这个神秘的是什么?如果它是非标准的,为什么(或何时)使用它是个好主意?