如何对邮件发送功能进行单元测试

时间:2011-06-17 06:45:09

标签: c# unit-testing mocking

我有一个创建报告并将其发送给用户的功能。 我所做的是为电子邮件功能创建一个模拟器,并验证是否调用了电子邮件类的“发送”功能。

所以现在我知道函数被调用了,但是如何对Send()函数的主体进行单元测试呢?如何证明主题和正文是正确的,并且附件附在电子邮件中?

6 个答案:

答案 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实现。通过这种方式发送了一封真实的电子邮件。