Mockito verifica l'ordine / la sequenza delle chiamate al metodo


205

C'è un modo per verificare se a Mockito methodOneviene chiamato prima 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();
    }
}

Risposte:


305

InOrder ti aiuta a farlo.

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
Questo è corretto, anche se qui non sono necessarie chiamate a fare Niente se non come segnaposto per altri stub. Mockito accetterà silenziosamente chiamate a metodi nulli per impostazione predefinita.
Jeff Bowman,

1
Li accetta mentre l'oggetto non ha dipendenze se l'oggetto ha dipendenze ci sarà un'eccezione =)
Koitoer

14
considerare inOrder.verifyNoMoreInteractions();dopo l'ultima verifica in questo esempio per verificare che non siano state effettuate altre chiamate.
DwB,

1
Solo per chiarire: è sicuro definire in Ordine appena prima di verificare - dopo aver invocato alcuni metodi (testati) su beffe.
user3078523

I risultati sono gli stessi per inOrder(firstMock, secondMock)e inOrder(secondMock, firstMock)? Forse puoi aggiornare la risposta per prendere nota al riguardo.
Kevinevpe,

95

Nota che puoi anche usare la classe InOrder per verificare che vari metodi vengano chiamati in ordine su un singolo mock, non solo su due o più mock.

Supponiamo che io abbia due classi Fooe Bar:

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

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

Posso quindi aggiungere una classe di prova per verificare che Baril firstThenSecond()metodo che effettivamente chiama first(), quindi second(), e non second(), quindi first(). Vedi il seguente codice di prova:

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
Questo avrebbe dovuto essere un commento sulla risposta accettata, non una risposta completamente nuova.
ach

12
Non sono d'accordo con il tuo commento @ach L'esempio di codice aiuta, quindi una nuova risposta ha senso.
Snekse,

2
C'è un modo per verificare che lo stesso metodo venga chiamato due volte, ma per verificare l'ordine dei parametri passati? ad esempio prima find('foo'), quindifind('bar')
Snekse,

1
Sembra che questo potrebbe essere la mia risposta stackoverflow.com/questions/36573399/...
Snekse

3
Questo è in realtà un esempio migliore della risposta accettata perché mostra un uso più tipico didoNothing()
Archimede Trajano,

37

Sì, questo è descritto nella documentazione. Devi usare la classe InOrder .

Esempio (supponendo che due mock siano già stati creati):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

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

1

Con BDD lo è

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


}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.