2013-08-16 28 views
3

我有一個void函數,它發送電子郵件。我需要爲這個函數編寫測試。如何才能做到這一點?無效函數的NUnit測試(發送電子郵件)

public void SendAdminMail(string subject, string body, string adminAddress) 
    { 

     var email = Email. 
      From(ConfigurationManager.AppSettings["Mail.NoReply.Address"].ToString(CultureInfo.InvariantCulture)). 
      To(adminAddress). 
      Subject(subject). 
      Body(body). 
      UsingClient(GetOfficeClient()); 
     email.Message.SubjectEncoding = Encoding.UTF8; 
     email.Message.BodyEncoding = Encoding.UTF8; 

     email.Send(); 
    } 
+0

你見過這個:http://blogs.msdn.com/b/aconrad/archive/2007/09/07/science-project.aspx –

+0

你想做什麼叫做嘲笑...而且是99連接到依賴注入的時間的百分比...沒有一個或另一個,它是非常複雜的做你想做的事情。 – xanatos

回答

3

在這種情況下這將是非常困難 - 除非你將能夠通過反射莫名其妙切換Email(如有趣的是指出出juhan_h in his answer,可能現在不那麼難;))。

典型的解決方案是爲您的班級提供一個界面,例如interface EmailFactory。然後,你必須:

private EmailFactory emailFactory; 
public void SendAdminMail(string subject, string body, string adminAddress) 
{ 
    var email = emailFactory 
     .From(ConfigurationManager 
        .AppSettings["Mail.NoReply.Address"] 
        .ToString(CultureInfo.InvariantCulture)) 
     .To(adminAddress) 
     .Subject(subject) 
     .Body(body) 
     .UsingClient(GetOfficeClient()); 

    email.Message.SubjectEncoding = Encoding.UTF8; 
    email.Message.BodyEncoding = Encoding.UTF8; 

    email.Send(); 
} 

然後你可以給你的類提供這個工廠的存根,這將創建電子郵件嘲笑的,你可以驗證正確的行爲。

2

如果你碰巧的Visual Studio 2012 Ultimate或高級版,那麼你可以生成用於System.Net.Mail裝配僞造品組裝和使用。

有關假貨的更多信息,請登錄MSDN

如果你沒有VS2012旗艦版或高級版那麼我的回答是完全usless :)

+0

此更新還包含VS2012 Premium中的假貨:http://blogs.msdn.com/b/bharry/archive/2013/01/30/announcing-visual-studio-2012-update-2-vs2012-2。 aspx –

+0

謝謝我不知道。 –

2

我開始認爲單元測試應該在網絡電纜拔出時工作。

你究竟想要測試什麼?

您可以使用模擬或僞造,並驗證您是否按預期調用了方法。
可能證明能夠將這個類存根並使用其他地方的存根來確保其餘的測試在每次運行時都不發送電子郵件會更有用。

1

這怎麼辦?

它不是簡單的,除非你使用特定的庫或框架做了很多的解決方法,因爲你的方法違反了SRP原則,以測試這種方法。

儘管您的方法名爲SendAmdinMail,但實際上只有一條語句處理髮送,其中的email.Send()和其餘方法使用.NET API構建郵件消息。

你應該打破這種方法到像CreateMailBody,CreateHeader,LoadMailConfig不同部位和隱藏郵件發送一個抽象背後(接口,抽象類)這樣你就可以創建郵件發送服務的模擬。

這種方式,您還可以測試郵件正文的內容,你可以測試收件人等

1

什麼你想要寫的是一個integration test,而不是unit test

如果你想測試你的代碼調用了一些負責發送電子郵件的函數,那麼你想通過使用某種模擬框架來編寫單元測試,比如NSubstitute

[Test] 
public void ShouldSendEmail() 
{ 
    IEmailService mockEmailService = Substitute.For<IEmailService>(); 
    MyEmailSendingThingy thingUnderTest = new MyEmailSendingThingy(mockEmailService); 

    thingUnderTest.DoSomeWorkThatInvolvesSendingEmails(); 

    mockEmailService.Received().SendEmail("[email protected]", "[email protected]", "Subject", "Some Text"); 
} 

如果要測試應用程序實際發送的電子郵件是否需要編寫集成測試。有很多方法可以實現這一目標。

  1. 編寫測試,等待一段時間,然後從測試電子郵件帳戶中檢索電子郵件,並驗證它是否收到了期望的消息。
  2. 發送電子郵件到其被設置爲存儲其中然後可以通過測試代碼進行檢查投遞文件夾中的電子郵件的內部SMTP服務器。
  3. 模擬出一個SMTP端點和模仿的響應的東西調用一個SMTP服務器所期望的。然後,您可以驗證您的端點是否收到了預期的電子郵件。
  4. 模擬出使用Moles或僞造品的System.Mail組件。

1和2需要大量的精力,你必須考慮到發送電子郵件的異步特性。這意味着你將不得不睡覺你的程序或者使用某種觸發器等待電子郵件到達目的地,這應該儘可能地避免。

3有三個原因我個人的選擇。您可以在測試過程中託管它,使您的斷言更容易。其次它是可重用的,可以在任何測試框架中使用。第三,作爲獎勵,您可以更好地瞭解電子郵件的工作原理。

4我個人不喜歡嘲弄靜態或混凝土組件。它可能會導致不良的習慣和錯誤的代碼。然而,使用正確的工具可能是一件有用的事情,這可能是您測試代碼這部分的最佳方式。

最後確保你正在測試正確的東西。您不需要測試Microsoft是否正確編寫了System.Email組件,只需確保您正確調用組件即可。