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

fro*_*roi 179 java unit-testing mockito

有没有办法验证Mockito methodOne之前是否methodTwo有人打电话?

public class ServiceClassA {
    public void methodOne(){}
 }

public class ServiceClassB {
    public void methodTwo(){}
 }
Run Code Online (Sandbox Code Playgroud)
public class TestClass {
    public void method(){
        ServiceClassA serviceA = new ServiceClassA();
        ServiceClassB serviceB = new ServiceClassB();
        serviceA.methodOne();
        serviceB.methodTwo();
    }
}
Run Code Online (Sandbox Code Playgroud)

Koi*_*oer 258

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();
Run Code Online (Sandbox Code Playgroud)

  • 在本例中的最后一次验证之后考虑`inOrder.verifyNoMoreInteractions();`以验证没有进行其他调用. (14认同)
  • 这是正确的,虽然这里不需要调用doNothing,除非作为其他存根的占位符.默认情况下,Mockito将默默接受void方法调用. (5认同)
  • 它接受它们,而对象没有依赖关系,如果对象有依赖关系,则会出现异常 =) (2认同)
  • 澄清一下:在验证之前定义 inOrder 是安全的 - 在模拟上调用一些(经过测试的)方法之后。 (2认同)

ent*_*erd 86

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

假设我有两个类,Foo并且Bar:

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

public class Bar {
  public void firstThenSecond(Foo foo) {
    foo.first();
    foo.second();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,我可以添加一个测试类测试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();
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不同意你的评论@ach代码示例有帮助,所以一个新的答案是有道理的. (10认同)
  • 这应该是对已接受答案的评论,而不是一个全新的答案。 (2认同)
  • 有没有办法验证同一个方法被调用两次,但验证传入的参数的顺序?例如,首先是`find('foo')`,然后是`find('bar')` (2认同)
  • 实际上,这是比接受的答案更好的示例,因为它显示的用法比`doNothing()`更典型。 (2认同)

Lau*_*ntG 34

是的,这在文档中有描述.您必须使用InOrder类.

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

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();
Run Code Online (Sandbox Code Playgroud)


use*_*413 7

对于 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!")
        }
    }
Run Code Online (Sandbox Code Playgroud)

}