[英]Is there any way to Mock private method call inside another method in Junit5
以下是我想測試的方法,但據我所知 Junit5 不支持 PowerMockito。 那么有什么方法可以在另一個方法中模擬私有方法調用嗎?
public Class MyClass {
private void sendEmailNotification(Checklist Checklist){
EmailService emailService = new EmailService();
BaseDTO esDO = newFolderService.getFolderByUri(ServicesUtils.getDecodedCaseNodeUriFromSelfLink(Checklist.getEs_uri()));
String esName = esDO.getName();
SharedInfo sharedInfo = Checklist.getShared_info();
sharedInfo.setEng_space_name(esName);
String reviewer = Checklist.getReviewer();
String ChecklistUri = Checklist.getUri();
String ChecklistName = Checklist.getName();
String targetPhase = Checklist.getTarget_phase();
String comment = Checklist.getComment();
String submitter = Checklist.getSubmitter();
String appURL = Checklist.getShared_info().getApp_url();
String ChecklistLink = buildChecklistURL(appURL, ChecklistUri);
String emailBodyTemplate;
String emailSubject;
emailBodyTemplate = EmailTemplates.getEmailTemplateByName(EmailConstants.TEMPLATE_DELIVERABLE_ACCEPTED_REJECTED_WITH_COMMENTS);
emailSubject = String.format(EmailConstants.ACCEPT_REJECT_WITH_COMMENTS_SUBJECT, ChecklistName, targetPhase);
emailBodyTemplate = EmailTemplates.replaceSharedVariable(emailBodyTemplate, sharedInfo);
emailBodyTemplate = EmailTemplates.replaceVariable(emailBodyTemplate, EmailConstants.VAR_TARGET_PHASE, targetPhase);
emailBodyTemplate = EmailTemplates.replaceVariable(emailBodyTemplate, EmailConstants.VAR_REVIEWER, reviewer);
emailBodyTemplate = EmailTemplates.replaceVariable(emailBodyTemplate, EmailConstants.VAR_CHECKLIST_ITEM_NAME, ChecklistName);
emailBodyTemplate = EmailTemplates.replaceVariable(emailBodyTemplate, EmailConstants.VAR_COMMENT, comment);
emailBodyTemplate = EmailTemplates.replaceVariable(emailBodyTemplate, EmailConstants.VAR_CHECKLIST_ITEM_URL, ChecklistLink);
try {
emailService.sendEmail(submitter, EmailConstants.EMAIL_SENDER, emailSubject, emailBodyTemplate);
} catch (RuntimeException e) {
Checklist.addError(messages.get(E_ACCEPT_REJECT_SEND_EMAIL));
}
}
//Method to be tested
public void method(Checklist checklist){
/*Some Code*/
sendEmail(checklist); /* want to ignore this, as throwing NullPointerException*/
/*Some Code*/
}}
你是對的。 Powermock 還不支持 JUnit 5 並且在他們的官方 github 存儲庫中有一個未解決的問題。
似乎沒有任何簡單的方法可以使用 Junit5 運行器模擬私有方法,除非您當然決定使用自定義類加載器並進行字節碼操作。
但是,我建議您模擬用於發送 email 的依賴項,而不是 mocking 整個方法(除非該依賴項使用某種最終方法)。
如果你甚至不能這樣做,那么最好的方法是使用 Junit4 而不是 Junit5。
我建議將private
方法的 scope 更改為package
或protected
。 然后,您可以在擴展 class 的測試 class 中覆蓋它。
我不會嘗試模擬sendMail
方法中使用的所有服務,因為您的測試將依賴於sendMail
方法中的所有內容,即使它不需要它。 因此,只要sendMail
方法的內部結構發生變化,您的測試就必須更改。 這會很糟糕,因為您的測試不需要sendMail
方法 - 這就是您要模擬它的原因。
您的測試也將變得非常復雜,其中包含僅使sendMail
方法工作所需的所有模擬。
更好的方法是將 sendMail 方法提取到接口中,並使用當前 sendMail 方法的內容創建一個實現。
public interface ChecklistNotifier {
public void sendNotification(Checklist checklist);
}
public class EmailChecklistNotifier implements ChecklistNotifier {
public void sendNotification(Checklist checklist){
EmailService emailService = new EmailService();
BaseDTO esDO = newFolderService.getFolderByUri(ServicesUtils.getDecodedCaseNodeUriFromSelfLink(Checklist.getEs_uri()));
// ...
}
}
您的客戶 class 然后可以使用ChecklistNotifier
。
public class ClientClass {
private ChecklistNotifier notifier;
public ClientClass(ChecklistNotifier notifier){
this.notifier = notifier;
}
public void method(Checklist checklist){
/*Some Code*/
notifier.sendnotification(checklist);
/*Some Code*/
}}
}
現在,您可以輕松地在測試中創建一個ClientClass
實例並將其傳遞給ChecklistNotifier
模擬或只是一個簡單的實現。
這種方法也符合SOLID原則,因為您有
ClientClass
和EmailChecklistNotifier
的單一職責ClientClass
與郵件發送實現依賴關系解耦。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.