当尝试将Mockito与spring一起使用时,通过bean声明创建Mock对象...
<bean id="accountMapper" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="org.example.persistence.mybatis.mappers.AccountMapper" />
</bean>
...我在调用mockito时发现了一些奇怪的行为。当多次没有重置Mock对象时,例如:
Mockito.when(this.accountMapper.createBadGrammarException()).thenThrow(new BadSqlGrammarException("Bla", null, new SQLException()));
在测试过程中(在同一个模拟上)多次调用此代码(“mockito.when”)时,测试就会失败并出现错误(BadSqlGrammerException即使该异常实际上是预期的--如果不抛出异常,我会得到一个失败,并且手动抛出它很正常)。这是意料之中的行为吗?Mockito似乎建议每次都创建一个新的mock,这意味着为每个方法创建DAO...?
当我调用mockito.when方法两次时,究竟会发生什么?模仿者该作何反应?替换行为?无视它?不幸的是,大多数搜索只会得到如何为方法本身的多次调用返回不同的结果的结果,而不会得到对mockito的多次调用的预期结果。
我只是想在这里理解Mockito和最佳实践,因为仅仅因为它看起来有效就去做一些事情似乎是个坏主意...
简单的答案是:
当您编写mockito.when(Object.foomethod()).then()
时,实际上会调用foomethod()
。
另一个问题是,我们不能第一次观察它,因为它调用的是模拟对象。但是当我们第二次编写when
时,我们会为foomethod()
设置一些行为(我们以前设置了它,在您的示例中是异常)。
要更好地检查这一点,您可以spy
对象:
Bar spyBar = Mockito.spy(Bar.class)
when(spyBar.fooMethod()).then()...
并且将实际调用foomethod()
。
mockito.when
的一个问题是,您传递给它的参数是您试图存根的表达式。因此,当您对同一个方法调用使用mockito.when
两次时,第二次使用它时,实际上会得到您第一次使用的行为。
我实际上建议不要使用mockito.when
。当你使用它的时候,你会掉进很多陷阱--当你需要一些其他语法来代替的时候,你会掉进很多陷阱。“更安全”的替代语法是Mockito方法的“do”家族。
doReturn(value).when(mock).method(arguments ...);
doThrow(exception).when(mock).method(arguments ...);
doAnswer(answer).when(mock).method(arguments ...);
所以在你的情况下,你想
doThrow(new BadSqlGrammarException(??, ??, ??)).when(accountMapper).createBadGrammarException();
如果你是从Mockito开始的,那么我建议你学会使用“do”家族。它们是模拟void方法的唯一方法,Mockito文档特别提到了这一点。但只要可以使用mockito.when
,就可以使用它们。因此,如果你使用“do”一族,你将在测试中获得更多的一致性,而不是学习曲线。
有关必须使用“do”家族的情况的更多信息,请参阅我关于形成Mockito“语法”的答案。
问题内容: 当尝试通过Spring使用Mockito时,通过bean声明创建Mock对象… …我多次调用Mockito。时发现一些奇怪的行为,而没有重置Mock对象,例如: 一旦在测试期间(在同一模拟上)多次调用此代码(“ Mockito.when”),测试就会失败并显示错误(BadSqlGrammerException,即使实际上是预期的异常,我也会失败- 如果我不抛出异常,则手动抛出该异常就可
问题内容: 我有一个包含多个CTE的相当复杂的查询,但是其他人都从中提取了1个主要CTE,这是否会导致该主要CTE多次执行? 问题答案: 您可以这样使用CROSS JOIN: 这将防止的多次执行(有关实际执行计划,请参见属性)。 示例:如果执行此查询 使用数据库,那么实际的执行计划将是
问题内容: 我想我在这里描述的可能有个名字,但我不知道。所以我的第一个问题是要知道这种技术的名称。 这是一个示例:假设您正在网页上实现实时搜索。每次用户在搜索框中键入内容时,您都会触发一个新的搜索查询,并且结果会尽可能频繁地更新。这是一件愚蠢的事情,因为您发送的查询会超出实际需要。每2-3个字母发送一次请求,或者每100 ms最多发送一次请求就足够了。 因此,一种技术是安排在键入键之后立即执行的查
问题内容: 我想计算不超过n的平方和。假设n为4,则此代码生成一个列表,列出范围为0到4的地图对象: 轻松一点。现在在m上调用列表,然后求和: 意外的行为是,如果我再次运行最后一行,则总和为0: 我怀疑这是因为调用返回了一个空列表,但是我找不到这种行为的解释。有人可以帮我这个忙吗? 问题答案: 在Python 3中返回一个有状态的迭代器。有状态的迭代器在耗尽后可能只消耗一次,并且不产生任何值。 在
如何验证一个模拟对象根本没有被调用?我正在尝试使用Mockito测试一个接口方法的空实现。
问题内容: 我想知道如果在同一个对象上同步两次,在Java中是否会出现任何奇怪的行为? 场景如下 两种方法都使用该对象并对其进行同步。当第一个方法调用第二个方法时,它会被锁定而停止吗? 我不这么认为,因为它是同一个线程,但是我不确定是否可能会出现其他任何奇怪的结果。 问题答案: 同步块使用 可重入 锁,这意味着如果线程已经持有该锁,则它可以重新获取它而不会出现问题。因此,您的代码将按预期工作。 请