测试SMTP的替代方案?

时间:2010-02-04 17:56:46

标签: .net smtpclient

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

有没有人用过像no-ip.com这样的东西?还有其他选择吗?

5 个答案:

答案 0 :(得分:4)

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

  <system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory" from="me@myorg.com">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\TestMailDrop"/>
      </smtp>
    </mailSettings>
  </system.net>

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

(正如codekaizen所指出的,如果您不介意修改代码/硬编码drop文件夹并且在调试/发布模式下行为不同,这也可以在代码中完成。)

答案 1 :(得分:2)

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

使用AutoFixture.xUnit [来自@codekaizen,使用{名称提供的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,该TemporaryDirectoryFixture已使用适用于实时SMTP服务器的参数连接。

(完整性,这里是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 ); } }

{{1}}

答案 4 :(得分:0)

通常的答案是在IIS下本地运行SMTP,但是您需要注意发送给谁的人。实际上,发送到您常用的SMTP服务器并仅定位您域中的帐户可能会更好。