Mockito, yöntem çağrılarının sırasını / sırasını doğrular


206

Mockito'da daha methodOneönce methodTwoçağrılıp çağrılmadığını doğrulamanın bir yolu var mı ?

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

Yanıtlar:


306

InOrder bunu yapmanıza yardımcı olur.

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
Bu doğrudur, ancak doNubing çağrıları burada diğer stubbing için bir yer tutucu haricinde gerekli değildir. Mockito varsayılan olarak geçersiz yöntem çağrılarını sessizce kabul eder.
Jeff Bowman

1
Nesnenin bağımlılığı yoksa, nesnenin bağımlılığı varsa bunları kabul eder =)
Koitoer

16
inOrder.verifyNoMoreInteractions();başka bir arama yapılmadığını doğrulamak için bu örnekteki son doğrulamadan sonra düşünün .
DwB

1
Sadece açıklığa kavuşturmak için: alaylarda bazı (test edilmiş) yöntemleri çağırdıktan sonra, doğrulamadan hemen önce inOrder'ı tanımlamak güvenlidir.
user3078523

Sonuçlar için aynı mı inOrder(firstMock, secondMock)ve inOrder(secondMock, firstMock)? Bunun hakkında bir not yazmak için cevabı güncelleyebilirsiniz.
kevinarpe

96

InOrder sınıfını, yalnızca iki veya daha fazla alayla değil, tek bir alayla sırayla çeşitli yöntemlerin çağrıldığını doğrulamak için de kullanabileceğinizi unutmayın .

İki sınıf olduğunu varsayalım Foove Bar:

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

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

Ben o teste bir test sınıfı ekleyebilir Barbireyin firstThenSecond()yöntem aslında çağırır first(), sonra second()değil, second()daha sonra, first(). Aşağıdaki test koduna bakın:

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
Bu tamamen yeni bir cevap değil, kabul edilen cevap hakkında bir yorum olmalıdır.
ach

12
Ben yorum @ach katılmıyorum Kod örneği yardımcı olur, bu nedenle yeni bir yanıt mantıklı.
Snekse

2
Aynı yöntemin iki kez çağrıldığını doğrulamanın bir yolu var mı, ancak aktarılan parametrelerin sırasını doğrulayın? Örneğin find('foo'), Öncefind('bar')
Snekse

1
Görünüşe göre bu cevabım stackoverflow.com/questions/36573399/…
Snekse

3
Bu aslında kabul edilen cevaptan daha iyi bir örnek çünkü daha tipik bir kullanım gösteriyordoNothing()
Archimedes Trajano

38

Evet, bu belgelerde açıklanmaktadır. InOrder sınıfını kullanmanız gerekir .

Örnek (iki alayın önceden oluşturulduğu varsayılarak):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

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

1

BDD ile

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


}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.