Mockito 验证方法调用的顺序/顺序
Posted
技术标签:
【中文标题】Mockito 验证方法调用的顺序/顺序【英文标题】:Mockito verify order / sequence of method calls 【发布时间】:2014-03-21 00:23:05 【问题描述】:有没有办法验证在 Mockito 中 methodTwo
之前是否调用了 methodOne
?
public class ServiceClassA
public void methodOne()
public class ServiceClassB
public void methodTwo()
public class TestClass
public void method()
ServiceClassA serviceA = new ServiceClassA();
ServiceClassB serviceB = new ServiceClassB();
serviceA.methodOne();
serviceB.methodTwo();
【问题讨论】:
【参考方案1】:InOrder
帮助您做到这一点。
ServiceClassA firstMock = mock(ServiceClassA.class);
ServiceClassB secondMock = mock(ServiceClassB.class);
Mockito.doNothing().when(firstMock).methodOne();
Mockito.doNothing().when(secondMock).methodTwo();
//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);
//following will make sure that firstMock was called before secondMock
inOrder.verify(firstMock).methodOne();
inOrder.verify(secondMock).methodTwo();
【讨论】:
这是正确的,尽管这里不需要调用 doNothing,除非作为其他存根的占位符。默认情况下,Mockito 将静默接受 void 方法调用。 它接受它们,而对象没有依赖关系如果对象有依赖关系就会出现异常=) 在本例中的最后一次验证之后考虑inOrder.verifyNoMoreInteractions();
,以验证没有进行其他调用。
澄清一下:在验证之前定义 inOrder 是安全的 - 在调用模拟上的一些(经过测试的)方法之后。
inOrder(firstMock, secondMock)
和 inOrder(secondMock, firstMock)
的结果是否相同?也许您可以更新答案以对此进行说明。【参考方案2】:
请注意,您还可以使用 InOrder 类来验证是否在单个模拟上按顺序调用各种方法,而不仅仅是在两个或多个模拟上。
假设我有两个班级Foo
和Bar
:
public class Foo
public void first()
public void second()
public class Bar
public void firstThenSecond(Foo foo)
foo.first();
foo.second();
然后我可以添加一个测试类来测试Bar
的firstThenSecond()
方法实际上调用first()
,然后是second()
,而不是second()
,然后是first()
。见以下测试代码:
public class BarTest
@Test
public void testFirstThenSecond()
Bar bar = new Bar();
Foo mockFoo = Mockito.mock(Foo.class);
bar.firstThenSecond(mockFoo);
InOrder orderVerifier = Mockito.inOrder(mockFoo);
// These lines will PASS
orderVerifier.verify(mockFoo).first();
orderVerifier.verify(mockFoo).second();
// These lines will FAIL
// orderVerifier.verify(mockFoo).second();
// orderVerifier.verify(mockFoo).first();
【讨论】:
这应该是对已接受答案的评论,而不是全新的答案。 我不同意你的评论@ach 代码示例有帮助,所以一个新的答案是有意义的。 有没有办法验证同一个方法被调用了两次,但是验证传入参数的顺序?例如首先是find('foo')
,然后是find('bar')
看起来这可能是我的答案***.com/questions/36573399/…
这实际上是一个比公认答案更好的例子,因为它显示了比doNothing()
更典型的用法【参考方案3】:
是的,文档中对此进行了描述。您必须使用InOrder 类。
示例(假设已经创建了两个模拟):
InOrder inOrder = inOrder(serviceAMock, serviceBMock);
inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();
【讨论】:
【参考方案4】:对于 Kotlin 用户,你可以这样:
class MyTrackerTest
private val trackEventUseCase: TrackEventUseCase = mock()
private val sut = MyTracker(trackEventUseCase)
@Test
fun `trackSomething SHOULD invoke tracker use case twice with correct event names WHEN called`()
sut.trackSomething()
trackEventUseCase.inOrder
verify().invoke("Is it August?")
verify().invoke("No!")
【讨论】:
【参考方案5】:BDD 是
@Test
public void testOrderWithBDD()
// Given
ServiceClassA firstMock = mock(ServiceClassA.class);
ServiceClassB secondMock = mock(ServiceClassB.class);
//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder = inOrder(firstMock, secondMock);
willDoNothing().given(firstMock).methodOne();
willDoNothing().given(secondMock).methodTwo();
// When
firstMock.methodOne();
secondMock.methodTwo();
// Then
then(firstMock).should(inOrder).methodOne();
then(secondMock).should(inOrder).methodTwo();
【讨论】:
以上是关于Mockito 验证方法调用的顺序/顺序的主要内容,如果未能解决你的问题,请参考以下文章