Szpieg może być przydatny, gdy chcesz tworzyć testy jednostkowe dla starszego kodu .
Utworzyłem tutaj działający przykład https://www.surasint.com/mockito-with-spy/ , część z niego kopiuję tutaj.
Jeśli masz coś takiego jak ten kod:
public void transfer( DepositMoneyService depositMoneyService, WithdrawMoneyService withdrawMoneyService,
double amount, String fromAccount, String toAccount){
withdrawMoneyService.withdraw(fromAccount,amount);
depositMoneyService.deposit(toAccount,amount);
}
Możesz nie potrzebować szpiega, ponieważ możesz po prostu udawać usługę DepositMoneyService i WithdrawMoneyService.
Ale w przypadku niektórych starszych kodów zależność jest w kodzie w następujący sposób:
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);
}
Tak, możesz przejść do pierwszego kodu, ale potem API jest zmieniane. Jeśli ta metoda jest używana w wielu miejscach, musisz zmienić je wszystkie.
Alternatywą jest to, że możesz wyodrębnić zależność w następujący sposób:
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();
}
Następnie możesz użyć szpiega i wstrzyknąć zależność w następujący sposób:
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();
Więcej szczegółów w powyższym linku.