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.