Les espions peuvent être utiles lorsque vous voulez créer des tests unitaires pour du code hérité.
J'ai créé un exemple exécutable ici https://www.surasint.com/mockito-with-spy/, j'en ai copié une partie ici.
Si vous avez quelque chose comme ce code:
public void transfer( DepositMoneyService depositMoneyService, WithdrawMoneyService withdrawMoneyService,
double amount, String fromAccount, String toAccount){
withdrawMoneyService.withdraw(fromAccount,amount);
depositMoneyService.deposit(toAccount,amount);
}
Vous n'avez peut-être pas besoin d'un espion car vous pouvez simplement simuler DepositMoneyService et WithdrawMoneyService.
Mais avec certains codes hérités, la dépendance est dans le code comme ceci:
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);
}
Oui, vous pouvez le changer pour le premier code mais alors l'API est modifiée. Si cette méthode est utilisée en plusieurs endroits, vous devez tous les changer.
L'alternative est d'extraire la dépendance comme ceci:
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();
}
Ensuite, vous pouvez utiliser l'espion pour injecter la dépendance comme ceci:
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();
Plus de détails dans le lien ci-dessus.