簡體   English   中英

有沒有辦法在 Junit5 中的另一個方法中模擬私有方法調用

[英]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 更改為packageprotected 然后,您可以在擴展 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原則,因為您有

  • ClientClassEmailChecklistNotifier的單一職責
  • 使其打開關閉-您可以將其替換為模擬或其他實現,也許是短信通知
  • 一個隔離的接口 - ChecklistNotification
  • 反轉了依賴關系,因此將ClientClass與郵件發送實現依賴關系解耦。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM