tutorial mock method español all java testing mocking mockito

java - method - mockito verify



¿Cuál es la diferencia entre burlarse y espiar al usar Mockito? (4)

La respuesta está en la documentación :

Mocks parciales reales (desde 1.8.0)

Finalmente, después de muchos debates internos y discusiones en la lista de correo, se agregó soporte simulado parcial a Mockito. Anteriormente consideramos burlas parciales como olores de código. Sin embargo, encontramos un caso de uso legítimo para burlas parciales: más lecturas: here

Antes de la versión 1.8, espiar () no estaba produciendo simulacros reales parciales y era confuso para algunos usuarios.

callRealMethod() se introdujo después de spy() , pero spy () se dejó allí, por supuesto, para garantizar la compatibilidad con versiones anteriores.

De lo contrario, tienes razón: todos los métodos de un espía son reales a menos que estén apagados. Todos los métodos de un simulacro son callRealMethod() menos que se callRealMethod() a callRealMethod() . En general, preferiría usar callRealMethod() , porque no me obliga a usar la doXxx().when() lugar de la tradicional when().thenXxx()

¿Cuál sería un caso de uso para el uso de un espía Mockito?

Me parece que cada caso de uso de espionaje puede manejarse con un simulacro, usando callRealMethod.

Una diferencia que puedo ver es que si desea que la mayoría de las llamadas a métodos sean reales, guarda algunas líneas de código para usar un simulacro frente a un espía. ¿Es eso o me estoy perdiendo la imagen más grande?


Si hay un objeto con 8 métodos y tienes una prueba en la que deseas llamar a 7 métodos reales y un método, tienes dos opciones:

  1. Usando un simulacro deberías configurarlo invocando 7 callRealMethod y un método
  2. Usando un spy debes configurarlo anulando un método

La documentación oficial en doCallRealMethod recomienda usar un espía para burlas parciales.

Consulte también javadoc spy (Object) para obtener más información sobre los simulacros parciales. Mockito.spy () es una forma recomendada de crear simulaciones parciales. La razón es que garantiza que se invocan métodos reales contra objetos correctamente construidos porque usted es responsable de construir el objeto pasado al método spy ().


Spy puede ser útil cuando quiera crear pruebas unitarias para código heredado .

He creado un ejemplo ejecutable aquí https://www.surasint.com/mockito-with-spy/ , copio algo aquí.

Si tiene algo así como este código:

public void transfer( DepositMoneyService depositMoneyService, WithdrawMoneyService withdrawMoneyService, double amount, String fromAccount, String toAccount){ withdrawMoneyService.withdraw(fromAccount,amount); depositMoneyService.deposit(toAccount,amount); }

Puede que no necesite espía porque puede simplemente burlarse de DepositMoneyService y WithdrawMoneyService.

Pero con algunos, código heredado, la dependencia está en el código como este:

public void transfer(String fromAccount, String toAccount, double amount){ this.depositeMoneyService = new DepositMoneyService(); this.withdrawMoneyService = new WithdrawMoneyService(); withdrawMoneyService.withdraw(fromAccount,amount); depositeMoneyService.deposit(toAccount,amount); }

Sí, puedes cambiar al primer código pero luego cambia la API. Si este método está siendo utilizado por muchos lugares, debe cambiarlos todos.

Alternativa es que puedes extraer la dependencia de la siguiente manera:

public void transfer(String fromAccount, String toAccount, double amount){ this.depositeMoneyService = proxyDepositMoneyServiceCreator(); this.withdrawMoneyService = proxyWithdrawMoneyServiceCreator(); withdrawMoneyService.withdraw(fromAccount,amount); depositeMoneyService.deposit(toAccount,amount); } DepositMoneyService proxyDepositMoneyServiceCreator() { return new DepositMoneyService(); } WithdrawMoneyService proxyWithdrawMoneyServiceCreator() { return new WithdrawMoneyService(); }

Entonces puedes usar el espía para inyectar la dependencia de esta manera:

DepositMoneyService mockDepositMoneyService = mock(DepositMoneyService.class); WithdrawMoneyService mockWithdrawMoneyService = mock(WithdrawMoneyService.class); TransferMoneyService target = spy(new TransferMoneyService()); doReturn(mockDepositMoneyService) .when(target).proxyDepositMoneyServiceCreator(); doReturn(mockWithdrawMoneyService) .when(target).proxyWithdrawMoneyServiceCreator();

Más detalles en el enlace de arriba.


Diferencia entre un espía y un simulacro

Cuando Mockito crea un simulacro, lo hace desde la clase de un tipo, no desde una instancia real. El simulacro simplemente crea una instancia de shell bare-bones de la Clase, totalmente equipada para rastrear las interacciones con ella. Por otro lado, el espía envolverá una instancia existente. Todavía se comportará de la misma manera que la instancia normal; la única diferencia es que también se instrumentará para rastrear todas las interacciones con ella.

En el siguiente ejemplo, creamos un simulacro de la clase ArrayList:

@Test public void whenCreateMock_thenCreated() { List mockedList = Mockito.mock(ArrayList.class); mockedList.add("one"); Mockito.verify(mockedList).add("one"); assertEquals(0, mockedList.size()); }

Como puede ver, agregar un elemento a la lista de burlas no agrega nada en realidad; simplemente llama al método sin ningún otro efecto secundario. Por otro lado, un espía se comportará de manera diferente: en realidad llamará a la implementación real del método add y agregará el elemento a la lista subyacente:

@Test public void whenCreateSpy_thenCreate() { List spyList = Mockito.spy(new ArrayList()); spyList.add("one"); Mockito.verify(spyList).add("one"); assertEquals(1, spyList.size()); }

Aquí seguramente podemos decir que se llamó al método interno real del objeto porque cuando llamas al método size () obtienes el tamaño como 1, ¡pero este método de tamaño () no se ha burlado! Entonces, ¿de dónde viene 1? El método interno de tamaño real () se llama como size () no se burla (o se repite) y, por lo tanto, podemos decir que la entrada se agregó al objeto real.

Fuente: http://www.baeldung.com/mockito-spy + self notes.