回答
如果你只需要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