Spy puede ser útil cuando desea crear pruebas unitarias para código heredado .
He creado un ejemplo ejecutable aquí https://www.surasint.com/mockito-with-spy/ , copio algunos de ellos aquí.
Si tienes algo 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);
}
Es posible que no necesite espía porque simplemente puede burlarse de DepositMoneyService y WithdrawMoneyService.
Pero con algunos códigos heredados, la dependencia está en el código de esta manera:
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í, puede cambiar al primer código, pero luego se cambia la API. Si este método está siendo utilizado por muchos lugares, debe cambiarlos todos.
La alternativa es que puede extraer la dependencia de esta 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();
}
Luego puede 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.