Mockito verifica el orden/secuencia de llamadas a métodos

4 minutos de lectura

avatar de usuario
desde

¿Hay alguna manera de verificar si un methodOne se llama antes methodTwo en 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();
    }
}

avatar de usuario
Koitoer

InOrder te ayuda a hacer eso.

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

  • Esto es correcto, aunque las llamadas a doNothing no son necesarias aquí, excepto como marcador de posición para otros stubing. Mockito aceptará silenciosamente llamadas de métodos nulos de forma predeterminada.

    –Jeff Bowman

    20 de febrero de 2014 a las 10:34

  • Los acepta mientras el objeto no tenga dependencias si el objeto tiene dependencias habrá una excepción =)

    – Koitoer

    20 de febrero de 2014 a las 17:12

  • considerar inOrder.verifyNoMoreInteractions(); después de la última verificación en este ejemplo para verificar que no se realizaron otras llamadas.

    – DWB

    30 de junio de 2016 a las 19:02

  • Solo para aclarar: es seguro definir inOrder justo antes de verificar, después de invocar algunos métodos (probados) en simulacros.

    – usuario3078523

    16 de agosto de 2017 a las 16:33

  • ¿Los resultados son los mismos para inOrder(firstMock, secondMock) y inOrder(secondMock, firstMock)? Quizás pueda actualizar la respuesta para hacer una nota sobre esto.

    – Kevinarpe

    27 de diciembre de 2017 a las 10:49

avatar de usuario
empollón

Tenga en cuenta que también puede utilizar el En orden class para verificar que varios métodos se llamen en orden en un solo simulacro, no solo en dos o más simulacros.

Supongamos que tengo dos clases. Foo y Bar:

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

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

Luego puedo agregar una clase de prueba para probar eso Bar‘s firstThenSecond() el método realmente llama first()después second()y no second()después first(). Consulte el siguiente código de prueba:

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

  • Esto debería haber sido un comentario sobre la respuesta aceptada, no una respuesta completamente nueva.

    – ach

    14 de noviembre de 2016 a las 19:12

  • No estoy de acuerdo con su comentario @ach El ejemplo de código ayuda, por lo que tiene sentido una nueva respuesta.

    – Snekse

    14 de abril de 2017 a las 16:49

  • ¿Hay alguna manera de verificar que el mismo método se llame dos veces, pero luego verifique el orden de los parámetros pasados? por ejemplo, primero find('foo')después find('bar')

    – Snekse

    14/04/2017 a las 16:51

  • Parece que esta podría ser mi respuesta stackoverflow.com/questions/36573399/…

    – Snekse

    14 de abril de 2017 a las 17:03

  • En realidad, este es un mejor ejemplo que la respuesta aceptada porque muestra un uso más típico que doNothing()

    – Arquímedes Trajano

    1 mayo 2019 a las 15:06

avatar de usuario
laurentg

Sí, esto se describe en la documentación. Tienes que usar el En orden clase.

Ejemplo (suponiendo que ya se hayan creado dos simulacros):

InOrder inOrder = inOrder(serviceAMock, serviceBMock);

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

Para los usuarios de Kotlin, puede hacerlo de esta manera:

class MyTrackerTest {
    private val trackEventUseCase: TrackEventUseCase = mock()
    private val sut = MyTracker(trackEventUseCase)

    @Test
    fun `trackSomething SHOULD invoke tracker use case twice with correct event names WHEN called`() {
        sut.trackSomething()

        trackEventUseCase.inOrder {
            verify().invoke("Is it August?")
            verify().invoke("No!")
        }
    }

}

Con BDD es

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


}

  • que es willDoNothing() ¿haciendo ahi? ¿Dónde está la referencia? ¿Por qué precede?

    –Dirk Schumacher

    7 de junio a las 5:07

  • que es willDoNothing() ¿haciendo ahi? ¿Dónde está la referencia? ¿Por qué precede?

    –Dirk Schumacher

    7 de junio a las 5:07

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad