Spy có thể hữu ích khi bạn muốn tạo các bài kiểm tra đơn vị cho mã kế thừa .
Tôi đã tạo một ví dụ có thể chạy ở đây https://www.surasint.com/mockito-with-spy/ , tôi sao chép một số đây.
Nếu bạn có một cái gì đó giống như mã này:
public void transfer( DepositMoneyService depositMoneyService, WithdrawMoneyService withdrawMoneyService,
double amount, String fromAccount, String toAccount){
withdrawMoneyService.withdraw(fromAccount,amount);
depositMoneyService.deposit(toAccount,amount);
}
Bạn có thể không cần gián điệp vì bạn chỉ có thể giả lập DepositMoneyService và WithdrawMoneyService.
Nhưng với một số, mã kế thừa, sự phụ thuộc nằm trong mã như thế này:
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);
}
Có, bạn có thể thay đổi mã đầu tiên nhưng sau đó API được thay đổi. Nếu phương pháp này đang được sử dụng bởi nhiều nơi, bạn phải thay đổi tất cả chúng.
Thay thế là bạn có thể trích xuất sự phụ thuộc ra như thế này:
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();
}
Sau đó, bạn có thể sử dụng gián điệp tiêm phụ thuộc như thế này:
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();
Chi tiết hơn trong liên kết ở trên.