我有一个创建报告并将其发送给用户的功能。 我所做的是为电子邮件功能创建一个模拟器,并验证是否调用了电子邮件类的“发送”功能。
所以现在我知道函数被调用了,但是如何对Send()函数的主体进行单元测试呢?如何证明主题和正文是正确的,并且附件附在电子邮件中?
答案 0 :(得分:32)
可以通过以下方式完成。
第1步:导航到您的Web.Config
文件并向其添加以下标记。
<system.net>
<mailSettings>
<smtp deliveryMethod="SpecifiedPickupDirectory">
<specifiedPickupDirectory pickupDirectoryLocation="E:\MailTest\"/>
</smtp>
</mailSettings>
</system.net>
确保您为取件地点指定的目录必须存在。
第2步:现在测试您的电子邮件发送功能。我使用button_click
使用以下代码测试此功能。
SmtpClient smtp = new SmtpClient();
MailMessage message = new MailMessage("me@gmail.com", "me@yahoo.com","My Message Subject","This is a test message");
smtp.Send(message);
输出:它将使用randonly生成的GUID名称在文件夹中创建.eml
个文件,这是我们收到后可以看到的电子邮件。
对我来说,它在c127d1d5-255d-4a5a-873c-409e23002eef.eml
文件夹
E:\MailTest\
这样的文件
希望这会有所帮助:)
答案 1 :(得分:12)
在您的单元测试中,告诉您的模拟框架期望使用特定正文文本调用Send()
。
Rhino Mocks的例子:
var mockMail = MockRepository.GenerateMock<Mail>();
mockMail.Expect( m => m.Send("ExpectedFrom", "ExpectedTo", "ExpectedSubject", "ExpectedBodytext") );
mockMail.Send(...whatever...);
mockProvider.VerifyAllExpectations();
答案 2 :(得分:8)
我最近自己遇到过这个问题。尝试使用http://netdumbster.codeplex.com/。 此库允许您启动本地SMTP服务器并检查它收到的邮件。这一切都在内存AFAIK中处理,因此对测试的性能影响应该是最小的。
在测试中,您可以像这样创建服务器
SimpleSmtpServer server = SimpleSmtpServer.Start(25);
然后只需更改邮件发件人类的配置即可使用本地smtp服务器(localhost:25)。 邮件发送后,您可以像这样访问它
server.ReceivedEmail[0]
使用Data或MessageParts属性检查主题,正文和附件。
我希望这会有所帮助。
答案 3 :(得分:1)
有一种非常简单的方法可以在审批测试(www.approvaltests.com)或nuget中测试电子邮件内容。
代码很简单:
EmailApprovals.Verify(mail);
这将创建.eml文件,并允许您在outlook中查看结果。未来。更多,一旦您批准结果(将文件重命名为.approved),测试将通过而无需打开Outlook。
我已创建并将有关流程的简短视频上传到YouTube。
答案 4 :(得分:1)
至少在我的情况下,所有电子邮件发送都封装在“MailService”类中 - 所有发送调用都通过类中的send方法。发送方法是虚拟的 - 它所做的全部是新的SmtpClient,发送邮件等。对于我的单元测试,我有一个私有类MailServiceMock,它覆盖发送并且什么都不做。可以测试所有其他方法 - 但发送是短路的。
oleschri使用Rhino Mocks提供了一种更简单的方法(我认为任何模拟框架都可以正常工作) - 但是如果你对引入另一个依赖项犹豫不决,那么这可以让你的脚沾手嘲弄。答案 5 :(得分:0)
过去我发过真正的电子邮件,但我在默认的EMailGateway实现中使用了装饰模式。
所以我有一个EMailGatewayRedirect,可以将收件人更改为我自己的地址,在我的情况下,在顶部添加了一行,说明电子邮件是一个测试以及原始收件人地址是什么。
由于我使用的是DI容器,我只是在我的集成测试中将重定向网关实例化为我的IEMailGateway实现。通过这种方式发送了一封真实的电子邮件。