如何单元测试电子邮件发送?

Gig*_*aPr 22 .net c# unit-testing

我想测试我的电子邮件发送功能使用.NET(C#)框架或任何兼容的库,任何建议如何做?

why*_*eee 31

如果您只需要测试发送电子邮件,则可以像这样配置.config文件

<system.net>
    <mailSettings>
        <smtp deliveryMethod="SpecifiedPickupDirectory">
            <specifiedPickupDirectory pickupDirectoryLocation="C:\TempMail" />
        </smtp>
    </mailSettings>
</system.net>
Run Code Online (Sandbox Code Playgroud)

使用这些设置,您的邮件不会通过网络发送,而是作为您在pickupDirectoryLocation属性中配置的文件夹中的.eml扩展名的物理文件删除.您可以在System.IO命名空间中的类的帮助下检查它们.

MSDN文档在这里


Mat*_*eer 19

我不同意在单元测试期间实际发送电子邮件的概念.这要求IMO遇到很多麻烦,并且反对单元测试应该是什么.

在我的应用程序中,我有一个IMailManager界面与类似SendPasswordResetEmail(string emailAddress)的方法等.我在单元测试期间模拟了这个对象,并确保我的组件正在调用正确的邮件管理器方法.

我的实际生产实现MailManager通常在System.Net.Mail.SmtpClient内部使用,您不需要测试.让微软测试一下.您需要做的就是确保在部署时正确设置smtp设置,这不应该是单元测试的关注点.

如果您需要测试您的邮件组件本身,即确保它生成正确的邮件正文等,我建议嘲笑将该功能隔离到自包含单元测试中所需的内容.

  • @SleeperSmith这不是一个单元测试,这是一个与外部系统通信的集成测试.这种测试是必需的,但不是单元测试能力. (5认同)
  • 您如何知道您的 SendPasswordResetEmail 方法是否正确实施?你没有。这就是为什么你需要测试它。确实,我可能不会将这些称为单元测试,但无论如何都需要对其进行测试。 (2认同)
  • 问题是测试实际的'电子邮件发送功能'.我很确定'单元测试'的作者真的想到了一种集成测试. (2认同)

Fer*_*eia 12

您无需测试实际的电子邮件发送功能; 这是.NET框架的一部分,它已经过测试.

单元测试需要的是电子邮件创建业务逻辑.将其封装在这样的服务中:

public interface IPasswordResetEmailCreator
{
    MailMessage Create(string emailAddress);
}
Run Code Online (Sandbox Code Playgroud)

并实施它.然后为此实现编写单元测试,并验证它返回的MailMessage是否符合您的要求.

使用SpecsFor框架进行此单元测试的示例实现:

public class PasswordResetEmailCreatorSpecs
{
    public class given_a_registered_user : SpecsFor<PasswordResetEmailCreator>
    {
        private string _emailAddress;
        private MailMessage _email;

        protected override void Given()
        {
            _emailAddress = "user@example.org";
        }

        protected override void When()
        {
            _email = SUT.Create(_emailAddress);
        }

        [Test]
        public void then_the_body_must_contain_the_reset_uri()
        {
            _email.Body.ShouldContain("/Password/Reset/");
        }

        [Test]
        public void then_the_email_must_be_for_the_user()
        {
            _email.To[0].Address.ShouldEqual(_emailAddress);
        }

        [Test]
        public void then_the_subject_must_be_the_expected()
        {
            _email.Subject.ShouldEqual("Your email reset link");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Jos*_* M. 0

我通常有一个“OverrideEmailAddress”设置,我将其设置为我自己的电子邮件,然后您运行的任何电子邮件测试都不会发送给您的客户或他们最初发送给的任何人。我有一个发送所有电子邮件的辅助方法,该方法将使用该设置(如果存在)。您也可以选择在电子邮件底部添加原始收件人。

如果您需要确认已收到电子邮件,则必须编写一些代码来实际检查电子邮件地址,然后确认消息是否正确。

不确定这是否是你的意思。