2011-03-09 88 views
20

我想用.NET(C#)框架或任何兼容的庫來測試我的電子郵件發送功能,任何建議怎麼做?如何對電子郵件發送進行單元測試?

+0

當代碼執行時你收到一封電子郵件嗎? – 2011-03-09 22:27:38

+0

代碼是什麼樣的? – 2011-03-09 22:30:19

+0

也許你可以顯示你正在測試的*功能的代碼,你不覺得嗎? – 2011-03-09 22:38:15

回答

0

我通常有我設置爲我自己的電子郵件的「OverrideEmailAddress」設置,然後運行也不會去你的客戶或任何人,他們將原本去任何電子郵件測試。我有一個幫助器方法,我發送所有的電子郵件通過,這種方法將使用該設置,如果它存在。或者,您可以添加到原始收件人的電子郵件底部。

如果需要再確認的電子郵箱收到你就必須編寫一些代碼來實際檢查的電子郵件地址,然後確認該消息是正確的。

不知道這是不是你的意思。

31

如果你需要測試只發送電子郵件,你可以配置你的config文件這樣

<system.net> 
    <mailSettings> 
     <smtp deliveryMethod="SpecifiedPickupDirectory"> 
      <specifiedPickupDirectory pickupDirectoryLocation="C:\TempMail" /> 
     </smtp> 
    </mailSettings> 
</system.net> 

通過這些設置你的消息不通過網絡發送,但如丟棄在pickupDirectoryLocation屬性中配置的文件夾中帶有.eml擴展名的物理文件。您可以在System.IO命名空間中的類的幫助下檢查它們。

MSDN文檔是here

+0

在配置中擁有msdn鏈接會很好。 – mathk 2014-06-03 12:36:30

17

我的單元測試過程中實際發送電子郵件的概念不以爲然。這就要求IMO遇到很多麻煩,並且違背了單元測試應該考慮的內容。

在我的應用程序,我有一個IMailManager接口與像SendPasswordResetEmail(string emailAddress)的方法等。我在單元測試期間嘲笑這個對象,並確保我的組件正在調用正確的郵件管理器方法。

我的實際生產實施MailManager通常在內部使用System.Net.Mail.SmtpClient,您不需要測試。讓微軟測試一下。所有你需要做的就是確保你的smtp設置在部署時正確設置,這不應該成爲單元測試的問題。

如果您需要測試您的郵件組件本身,即確保它生成正確的郵件正文等,我建議嘲笑將此功能隔離爲自包含的單元測試所需的內容。

+1

你怎麼知道你的SendPasswordResetEmail方法是否正確實現?你沒有。這就是爲什麼你需要測試它。真的,我可能不會稱這些單元測試,但他們需要進行測試,無論。 – 2012-03-13 22:09:56

+3

@SleeperSmith這不是一個單元測試,這是一個集成測試,因爲它與外部系統進行通信。這種測試是必要的,但不是單元測試能力。 – 2012-06-18 13:56:29

+0

問題是測試實際的'電子郵件發送功能'。我非常確定'單元測試'作者真的想到了一種集成測試。 – whyleee 2012-08-26 01:56:52

0

我可能會寫一篇關於.NET SmtpClient類的頂部真的瘦抽象層。然後,我可以用模型類代替單元測試。當然,你將無法單元測試封裝,但無論如何它都應該實際上是微不足道的,幾乎不會改變。

0

有一個很簡單的方法來測試approvaltests電子郵件內容(www.approvaltests.com或的NuGet)。代碼很簡單:

EmailApprovals.Verify(mail); 

這將創建.eml文件,並允許您在Outlook中查看結果。此外,一旦您批准結果(將文件重命名爲「批准」),測試將通過而不打開前景。 (這是一個非常類似的過程@whyleee提到什麼,但不使用的配置文件。)

I have published a short video on the process on YouTube

11

您不需要測試實際的電子郵件發送功能;這是.NET框架的一部分,它已經過測試。

你需要單元測試的是電子郵件創建業務邏輯。將其封裝在如下服務中:

public interface IPasswordResetEmailCreator 
{ 
    MailMessage Create(string emailAddress); 
} 

並執行它。然後編寫一個這個實現的單元測試並驗證它返回的郵件消息符合您的要求。

使用SpecsFor框架這個單元測試的樣本實施:

public class PasswordResetEmailCreatorSpecs 
{ 
    public class given_a_registered_user : SpecsFor<PasswordResetEmailCreator> 
    { 
     private string _emailAddress; 
     private MailMessage _email; 

     protected override void Given() 
     { 
      _emailAddress = "[email protected]"; 
     } 

     protected override void When() 
     { 
      _email = SUT.Create(_emailAddress); 
     } 

     [Test] 
     public void then_the_body_must_contain_the_reset_uri() 
     { 
      _email.Body.ShouldContain("/Password/Reset/"); 
     } 

     [Test] 
     public void then_the_email_must_be_for_the_user() 
     { 
      _email.To[0].Address.ShouldEqual(_emailAddress); 
     } 

     [Test] 
     public void then_the_subject_must_be_the_expected() 
     { 
      _email.Subject.ShouldEqual("Your email reset link"); 
     } 
    } 
} 
0

如果你想測試它,我會建議看mail4net:www.mail4net.com

這是一個商業產品,但它允許您使用虛假的SMTP服務發送電子郵件,然後查詢該假冒。

// Create Mail4Net FakeClient. 
var client = new Mail4Net.Client.FakeClient(); 

// Send email. 
client.Send(from, to, subject, body); 

然後,你就可以查詢客戶端:

// Count the number of emails sent. 
var count = client.Count(); 

// Get first email. 
var message = client[0]; 
0

我的快速和骯髒的方法是非常相似的top answer by whylee除了它不需要接觸任何配置,文件(因爲我可能需要您的電子郵件發送代碼中不同的單元測試不同的設置)

if (ConfigurationManager.AppSettings["smtpDir"] == null) 
    smtp.DeliveryMethod = SmtpDeliveryMethod.Network; 
else 
{ 
    smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory; 
    smtp.PickupDirectoryLocation = ConfigurationManager.AppSettings["smtpDir"]; 
} 

在您的單元測試

ConfigurationManager.AppSettings["smtpDirectory"] = dir; 

//do some testing then change it back 

ConfigurationManager.AppSettings["smtpDirectory"] = null; 

PS。我知道所有的缺點,但以防萬一有人需要這個...

相關問題