Mockitoはメソッド呼び出しの順序/シーケンスを検証します


205

MockitoでmethodOne以前methodTwoに呼び出されているかどうかを確認する方法はありますか?

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

回答:


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メソッド呼び出しを黙って受け入れます。
Jeff Bowman、

1
オブジェクトに依存関係がない場合は、オブジェクトを受け入れます。オブジェクトに依存関係がある場合、例外が発生します=)
Koitoer

14
inOrder.verifyNoMoreInteractions();この例の最後の検証の後で、他の呼び出しが行われていないことを検証することを検討してください。
DwB 2016年

1
明確にするために:検証の直前-モックでいくつかの(テストされた)メソッドを呼び出した後でinOrderを定義しても安全です。
user3078523 2017

結果はで同じですinOrder(firstMock, secondMock)inOrder(secondMock, firstMock)?おそらく、回答を更新してこれについて書き留めることができます。
kevinarpe 2017

95

InOrderクラスを使用して、2つ以上のモックだけでなく、1つのモックでさまざまなメソッドが順番に呼び出されることを確認することもできます。

2つのクラスがFooあり、Bar

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
これは、まったく新しい回答ではなく、受け入れられた回答に対するコメントである必要があります。
ACH

12
コメントに同意しません@achコードサンプルは役に立ちますので、新しい答えは理にかなっています。
Snekse

2
同じメソッドが2回呼び出されたことを確認する方法はありますが、渡されたパラメーターの順序を確認しますか?例:最初find('foo')、次にfind('bar')
Snekse

1
このように見えますが、私の回答であるかもしれないstackoverflow.com/questions/36573399/...
Snekse

3
それはより多くの典型的な使い方を示していので、これは実際に受け入れ答えよりも良い例ですdoNothing()
アルキメデストラハノ

37

はい、これはドキュメントに記載されています。InOrderクラスを使用する必要があります。

例(2つのモックがすでに作成されていると想定):

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


}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.