回答
如果你只需要t O檢查電子郵件被髮送到正確的地址,並用正確的內容,最簡單的方法是通過編輯應用程序或web.config文件中使用投遞文件夾:
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory" from="[email protected]">
<specifiedPickupDirectory pickupDirectoryLocation="C:\TestMailDrop"/>
</smtp>
</mailSettings>
</system.net>
這將導致電子郵件被創建爲指定目錄中的文件。您甚至可以加載這些文件並將其作爲單元測試的一部分進行驗證。
(如codekaizen指出,這也可以在代碼中完成,如果你不介意修改代碼/硬編碼投遞文件夾,並具有行爲在調試/釋放模式有所不同。)
+1以充分利用不良情況。 – 2010-02-04 18:26:09
聽起來像現在最好的選擇 - 加上它顯然是時候把我的簡歷上careers.stackoverflow.com :) – chris 2010-02-04 19:25:40
我要限制自己的技術建議,而不是職業建議。但是,是的,如果你的僱主希望你做一些事情,然後阻止你做到這一點,你就會遇到問題。 – 2010-02-04 20:50:45
通常的答案是在IIS下本地運行SMTP,但您需要注意發送給誰。實際上,發送到通常的SMTP服務器並僅定位到您的域中的帳戶可能會更好。
不幸的是,甚至無法做到這一點。 – chris 2010-02-04 18:12:21
哇。好的,那麼技術愛好者的答案可能是最好的。 – 2010-02-04 18:23:50
我會同意上面的...設置您自己的測試SMTP服務器,並將其用於您的測試。
這裏的一些信息,讓你在正確的軌道上:
http://service1.symantec.com/support/ent-gate.nsf/docid/2007241920754398
+1提供參考。 – 2010-02-04 18:11:43
您可以將電子郵件保存到磁盤:
#if DEBUG
smtpClient.PickupDirectoryLocation = "\\Path\\to\\save\\folder";
smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
smtpClient.Send(msg);
#endif
這可行,但我更喜歡app.config解決方案,因爲它不依賴於調試或發佈版本。 – 2010-02-04 20:29:39
是的,這是更好的方法......我剛剛忘了如何做配置技巧。 – codekaizen 2010-02-04 21:37:23
+1你不想在配置文件中使用硬連線路徑,否則它將成爲維護的噩夢。您應該創建一個臨時目錄夾具,在測試之後將其擦除並針對其內容進行聲明 – 2012-08-10 11:22:05
從@ Riffing codekaizen,使用AutoFixture.xUnit [其可作爲一個包的xUnit該名稱]: -
[Theory, AutoData]
public static void ShouldSendWithCorrectValues(string anonymousFrom, string anonymousRecipients, string anonymousSubject, string anonymousBody)
{
anonymousFrom += "@b.com";
anonymousRecipients += "@c.com";
using (var tempDir = new TemporaryDirectoryFixture())
{
var capturingSmtpClient = new CapturingSmtpClientFixture(tempDir.DirectoryPath);
var sut = new EmailSender(capturingSmtpClient.SmtpClient);
sut.Send(anonymousFrom, anonymousRecipients, anonymousSubject, anonymousBody);
string expectedSingleFilename = capturingSmtpClient.EnumeratePickedUpFiles().Single();
var result = File.ReadAllText(expectedSingleFilename);
Assert.Contains("From: " + anonymousFrom, result);
Assert.Contains("To: " + anonymousRecipients, result);
Assert.Contains("Subject: " + anonymousSubject, result);
Assert.Contains(anonymousBody, result);
}
}
CapturingSmtpClientFixture
僅在試驗中使用的上下文
class CapturingSmtpClientFixture
{
readonly string _path;
readonly SmtpClient _smtpClient;
public CapturingSmtpClientFixture(string path)
{
_path = path;
_smtpClient = new SmtpClient { DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory, PickupDirectoryLocation = _path };
}
public SmtpClient SmtpClient
{
get { return _smtpClient; }
}
public IEnumerable<string> EnumeratePickedUpFiles()
{
return Directory.EnumerateFiles(_path);
}
}
然後,您需要做的就是確保您的實際代碼提供的SmtpClient
已經與適用於實時SMTP服務器的參數連接起來。
(爲了完整起見,這裏是TemporaryDirectoryFixture
): -
public class TemporaryDirectoryFixture : IDisposable
{
readonly string _directoryPath;
public TemporaryDirectoryFixture()
{
string randomDirectoryName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
_directoryPath = Path.Combine(Path.GetTempPath(), randomDirectoryName);
Directory.CreateDirectory(DirectoryPath);
}
public string DirectoryPath
{
get { return _directoryPath; }
}
public void Dispose()
{
try
{
if (Directory.Exists(_directoryPath))
Directory.Delete(_directoryPath, true);
}
catch (IOException)
{
// Give other process a chance to release their handles
// see http://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true/1703799#1703799
Thread.Sleep(0);
try
{
Directory.Delete(_directoryPath, true);
}
catch
{
var longDelayS = 2;
try
{
// This time we'll have to be _really_ patient
Thread.Sleep(TimeSpan.FromSeconds(longDelayS));
Directory.Delete(_directoryPath, true);
}
catch (Exception ex)
{
throw new Exception(@"Could not delete " + GetType() + @" directory: """ + _directoryPath + @""" due to locking, even after " + longDelayS + " seconds", ex);
}
}
}
}
}
和骨架EmailSender
:
public class EmailSender
{
readonly SmtpClient _smtpClient;
public EmailSender(SmtpClient smtpClient)
{
if (smtpClient == null)
throw new ArgumentNullException("smtpClient");
_smtpClient = smtpClient;
}
public void Send(string from, string recipients, string subject, string body)
{
_smtpClient.Send(from, recipients, subject, body);
}
}
我嘗試使用您的TemporaryDirectoryFixture作爲AutoData。 Dispose方法被Xunit調用,但我得到一個IOException對路徑的訪問被拒絕。如果我在測試中使用了一個使用語句,它會起作用。也許Xunit跑步者有不同的權限比測試代碼會導致這種情況? – 2015-07-27 05:10:46
@EricRoller是v2還是v1?在這兩種情況下,測試都在AppDomain內部運行(儘管v2最近添加了一個開關以允許禁止此操作)。然而,在v1和v2之間,參數的創建方式和/或Dispose會有很大的不同。在v1中,args的處理沒有發生,沒有太多的詭計(自定義'FactAttribute's等)。我沒有花費足夠的時間閱讀有關「一次性」的文檔,以瞭解除了說'做'使用'會很容易理解,除非您有足夠的測試可以獲益使它值得 – 2015-07-27 08:05:54
我正在使用v2,並只是想出發生了什麼。我修改了TemporaryDirectoryFixture來擴展DirectoryInfo。然後Autofixture使用隨機數據調用所有公共設置器,這些數據在刪除目錄時會以某種方式導致訪問被拒絕。我解決了這個問題,所有公共設置者都沒有操作。感謝TemporaryDirectoryFixture代碼,它使得編寫小集成測試非常快捷。 – 2015-07-28 11:34:20
- 1. 測試流星包 - TinyTest的替代品?
- 2. DNX和XUnit的Visual Studio測試運行器的替代品?
- 3. XML單元測試:用於.NET的XmlUnit替代品?
- 4. 用於IE9測試版的BlockUI替代品?
- 5. @「」的替代品?
- 6. 積分測試代替單元測試
- 7. SMTP連接測試
- 8. ASIHTTP的最佳替代品,替代品或替代品用於下載隊列
- 9. 用於測試代碼片段的Visual Studio的輕量級替代品?
- 10. Pieceable的替代品
- 11. NowJS的替代品
- 12. Flash的替代品?
- 13. RelativeLayout的替代品?
- 14. JMegahal的替代品
- 15. JodReports的替代品
- 16. Git的替代品?
- 17. YQL的替代品
- 18. window.scrollMaxY的替代品?
- 19. FMINCON的替代品
- 20. SuperSized的替代品
- 21. reCAPCTHA的替代品?
- 22. wx.lib.masked.NumCtrl的替代品
- 23. webistrano的替代品?
- 24. PathListBox的替代品
- 25. CKAN的替代品
- 26. SwaggerHub的替代品
- 27. Wakelocks的替代品?
- 28. fancybox的替代品?
- 29. Dreamweaver的替代品?
- 30. pdftohtml的替代品
究竟是你想做些什麼? – SLaks 2010-02-04 17:59:18
用戶提交表格,我們發送確認郵件。不是火箭科學。 – chris 2010-02-04 18:10:42
編寫您的PC上運行的自己的SMTP服務器。 – 2010-02-04 18:27:36