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

本文关键字:功能 单元测试 | 更新日期: 2023-09-27 17:59:38

我有一个函数,它创建一个报告并将其发送给用户。我所做的是为电子邮件函数创建一个mock,并验证是否调用了电子邮件类的"send"函数。

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

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

可以通过以下方式完成。

步骤1:导航到您的Web.Config文件并添加以下标签。

<system.net>
    <mailSettings>
        <smtp deliveryMethod="SpecifiedPickupDirectory">
            <specifiedPickupDirectory pickupDirectoryLocation="E:'MailTest'"/>
        </smtp>
    </mailSettings>
</system.net>

请确保为提取位置指定的目录必须存在。

第二步:现在测试你的电子邮件发送功能。我已经使用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文件,这是我们收到它后可以看到的电子邮件。对我来说,它在E:'MailTest'文件夹中创建了一个类似c127d1d5-255d-4a5a-873c-409e23002eef.eml的文件

希望这有帮助:)

在单元测试中,告诉您的mocking框架期望调用带有特定正文的Send()

犀牛模型示例:

var mockMail = MockRepository.GenerateMock<Mail>();
mockMail.Expect( m => m.Send("ExpectedFrom", "ExpectedTo", "ExpectedSubject", "ExpectedBodytext") );
mockMail.Send(...whatever...);
mockProvider.VerifyAllExpectations();

我最近自己也遇到了这个问题。尝试使用http://netdumbster.codeplex.com/.此库允许您启动本地SMTP服务器并检查它收到的邮件。这一切都在内存AFAIK中处理,因此对测试的性能影响应该最小。

在你的测试中,你创建了这样的服务器

SimpleSmtpServer server = SimpleSmtpServer.Start(25);

然后,只需更改邮件发件人类的配置即可使用本地smtp服务器(localhost:25)。邮件发送后,您可以像这样访问

server.ReceivedEmail[0]

并使用Data或MessageParts属性来检查主题、正文和附件。

我希望这能有所帮助。

至少在我的情况下,所有的电子邮件发送都封装在"MailService"类中,并且所有的send调用都通过该类中的send方法。send方法是虚拟的,它所做的只是新建SmtpClient、发送邮件等。对于我的单元测试,我有一个私有类MailServiceMock,它覆盖send,什么也不做。所有其他方法都可以测试,但send是短路的。

oleschri使用Rhino Mocks提供了一种更简单的方法来实现这一点(我认为任何mocking框架都可以很好地工作)——然而,如果你对引入另一个依赖关系犹豫不决,这可能会让你的脚被手动mocking弄湿。

有一种非常简单的方法可以测试approvaltests(www.approvaltests.com)或nuget)中的电子邮件内容

代码很简单:

 EmailApprovals.Verify(mail);

这将创建.eml文件,并允许您在outlook中查看结果。Future.more,一旦您批准了结果(将文件重命名为.approved),测试将在不打开Outlook的情况下通过。

我创建了一个关于这个过程的短视频并上传到了YouTube上。

过去我发送过真实的电子邮件,但在默认的EMailGateway实现中使用了decorator模式。

因此,我有一个EMailGatewayRedirect,它会将收件人更改为我自己的地址,在我的情况下,还会在顶部添加一行,说明电子邮件是一个测试,以及原始收件人地址是什么。

由于我使用DI容器,所以在集成测试中,我只是将重定向网关实例化为我的IEMailGateway实现。通过这种方式发送了一封真实的电子邮件。