Шпигун може бути корисним, коли ви хочете створити одиничні тести для застарілого коду .
Я створив примірний приклад тут https://www.surasint.com/mockito-with-spy/ , деякі з них копіюю тут.
Якщо у вас є щось подібне до цього коду:
public void transfer( DepositMoneyService depositMoneyService, WithdrawMoneyService withdrawMoneyService,
double amount, String fromAccount, String toAccount){
withdrawMoneyService.withdraw(fromAccount,amount);
depositMoneyService.deposit(toAccount,amount);
}
Можливо, вам не потрібен шпигун, оскільки ви можете просто знущатися над MoneyMoneyService та WithdrawMoneyService.
Але з деяким застарілим кодом залежність знаходиться в такому коді:
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);
}
Так, ви можете змінити перший код, але потім змінити API. Якщо цей метод використовується в багатьох місцях, вам доведеться їх змінити.
Альтернативою є те, що ви можете витягти залежність так:
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();
}
Тоді ви можете використовувати шпигуна, який вводить залежність так:
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();
Більш детально за посиланням вище.