测试 SMTP 的替代方案?

发布于 2024-08-19 22:57:46 字数 106 浏览 6 评论 0原文

我正在尝试开发一个发送电子邮件的应用程序,但我们的内部网络被锁定得非常严密,所以我无法使用我们的内部邮件服务器进行中继。

有人用过 no-ip.com 之类的东西吗?还有其他选择吗?

I'm trying to develop an app that sends email, and our internal network is locked down pretty tight, so I can't relay using our internal mail servers.

Has anyone ever used something like no-ip.com? Are there any other alternatives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

习ぎ惯性依靠 2024-08-26 22:57:46

如果您只需要检查电子邮件是否发送到正确的地址并包含正确的内容,最简单的方法是通过编辑应用程序或 web.config 文件来使用放置文件夹:

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory" from="[email protected]">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\TestMailDrop"/>
      </smtp>
    </mailSettings>
  </system.net>

这将导致电子邮件邮件被创建为指定目录中的文件。您甚至可以加载文件并验证它们作为单元测试的一部分。

(正如 codekaizen 指出的,如果您不介意修改代码/硬编码放置文件夹并在调试/发布模式下具有不同的行为,也可以在代码中完成此操作。)

If you just need to check that the e-mails are being sent to the correct addresses and with the correct contents, the easiest way is to use a drop folder by editing the app or web.config file:

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory" from="[email protected]">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\TestMailDrop"/>
      </smtp>
    </mailSettings>
  </system.net>

This will result in the e-mails being created as files in the specified directory. You can even then load the files and verify them as part of a unit test.

(As codekaizen points out, this can also be done in code if you don't mind modifying the code/hardcoding the drop folder and having the behavior differing in debug/release mode.)

梦途 2024-08-26 22:57:46

您可以将电子邮件保存到磁盘:

#if DEBUG
smtpClient.PickupDirectoryLocation = "\\Path\\to\\save\\folder";
smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
smtpClient.Send(msg);
#endif

You can save the email to disk:

#if DEBUG
smtpClient.PickupDirectoryLocation = "\\Path\\to\\save\\folder";
smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
smtpClient.Send(msg);
#endif
↘紸啶 2024-08-26 22:57:46

来自 @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 );
    }
}

Riffing from @codekaizen, using AutoFixture.xUnit [which is available as an XUnit package by that name]:-

    [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 is only used in a test context-

    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 );
        }
    }

All you need to do then is make sure your actual code supplies an SmtpClient that has been wired up with parameters appropriate to the live SMTP server.

(For completeness, here is 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 );
                }
            }
        }
    }
}

and a skeleton 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 );
    }
}
清浅ˋ旧时光 2024-08-26 22:57:46

通常的答案是在 IIS 下本地运行 SMTP,但您需要小心发送给谁。实际上,最好发送到您常用的 SMTP 服务器并仅定位您域内的帐户。

The usual answer is to run SMTP locally under IIS, but you need to be careful about who you're sending to. It might actually be better to send to your usual SMTP server and target only accounts within your domain.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文