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.