Mockito验证方法调用的顺序/顺序


205

有没有一种方法可以验证在Mockito中是否曾经methodOne调用过methodTwoa?

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

Answers:


305

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

5
这是正确的,尽管这里不需要调用doNothing,只是作为其他存根的占位符。默认情况下,Mockito将静默接受void方法调用。
杰夫·鲍曼

1
它接受它们,而对象没有依赖关系,如果对象具有依赖关系,将有一个例外=)
Koitoer 2014年

14
考虑inOrder.verifyNoMoreInteractions();在此示例中的最后一次验证之后,以验证是否未进行其他调用。
DwB

1
只是要澄清一下:在验证之前定义inOrder是安全的-在模拟上调用某些(经过测试的)方法之后。
user3078523

所有的结果都是一样的inOrder(firstMock, secondMock)inOrder(secondMock, firstMock)?也许您可以更新答案以对此进行注释。
kevinarpe

94

请注意,您还可以使用InOrder类来验证是否在单个模拟上(而不是仅在两个或多个模拟上)按顺序调用了各种方法。

假设我有两个类FooBar

public class Foo {
  public void first() {}
  public void second() {}
}

public class Bar {
  public void firstThenSecond(Foo foo) {
    foo.first();
    foo.second();
  }
}

然后,我可以添加一个测试类测试BarfirstThenSecond()方法实际上是调用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();
  }
}

1
这应该是对已接受答案的评论,而不是一个全新的答案。
2016年

12
我不同意您的评论@ach代码示例会有所帮助,因此有一个新答案是有意义的。
Snekse

2
有没有一种方法可以验证同一方法是否被调用两次,但是可以验证传入参数的顺序?例如首先find('foo'),然后find('bar')
Snekse

1
看起来这可能是我的答案stackoverflow.com/questions/36573399/…–
Snekse

3
实际上,这是比接受的答案更好的示例,因为它显示了比doNothing()
Archimedes Trajano

37

是的,在文档中对此进行了描述。您必须使用InOrder类。

示例(假设已经创建了两个模拟):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();

1

使用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();


}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.