Mockito memverifikasi urutan / urutan pemanggilan metode

205

Apakah ada cara untuk memverifikasi jika a methodOnedipanggil sebelumnya methodTwodi Mockito?

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

Jawaban:

305

InOrder membantu Anda melakukan itu.

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();
Koitoer
sumber
5
Ini benar, meskipun panggilan ke doNothing tidak diperlukan di sini kecuali sebagai pengganti untuk stubbing lainnya. Mockito akan secara diam-diam menerima panggilan metode batal secara default.
Jeff Bowman
1
Itu menerima mereka sementara objek tidak memiliki dependensi jika objek memiliki dependensi akan ada pengecualian =)
Koitoer
14
pertimbangkan inOrder.verifyNoMoreInteractions();setelah verifikasi terakhir dalam contoh ini untuk memverifikasi bahwa tidak ada panggilan lain yang dibuat.
DwB
1
Hanya untuk mengklarifikasi: Aman untuk mendefinisikan inOrder sebelum memverifikasi - setelah menerapkan beberapa metode (yang diuji) pada tiruan.
user3078523
Apakah hasilnya sama untuk inOrder(firstMock, secondMock)dan inOrder(secondMock, firstMock)? Mungkin Anda dapat memperbarui jawabannya untuk membuat catatan tentang ini.
kevinarpe
95

Perhatikan bahwa Anda juga dapat menggunakan kelas InOrder untuk memverifikasi bahwa berbagai metode dipanggil secara berurutan, bukan hanya pada dua atau lebih mengejek.

Misalkan saya memiliki dua kelas Foodan Bar:

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

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

Saya kemudian dapat menambahkan kelas tes untuk menguji bahwa Bar's firstThenSecond()metode benar-benar memanggil first(), maka second(), dan tidak second(), kemudian first(). Lihat kode tes berikut:

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();
  }
}
entpnerd
sumber
1
Ini seharusnya merupakan komentar pada jawaban yang diterima, bukan jawaban yang sama sekali baru.
ach
12
Saya tidak setuju dengan komentar Anda @ach. Contoh kode membantu, jadi jawaban baru masuk akal.
Snekse
2
Apakah ada cara untuk memverifikasi metode yang sama disebut dua kali, tetapi memverifikasi urutan parameter yang diteruskan? mis. Pertama find('foo'), lalufind('bar')
Snekse
1
Sepertinya ini mungkin jawaban saya stackoverflow.com/questions/36573399/...
Snekse
3
Ini sebenarnya adalah contoh yang lebih baik daripada jawaban yang diterima karena ini menunjukkan penggunaan yang lebih khas daripadadoNothing()
Archimedes Trajano
37

Ya, ini dijelaskan dalam dokumentasi. Anda harus menggunakan kelas InOrder .

Contoh (dengan asumsi dua ejekan sudah dibuat):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

inOrder.verify(serviceAMock).methodOne();
inOrder.verify(serviceBMock).methodTwo();
LaurentG
sumber
1

Dengan BDD itu

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


}
Thracian
sumber