Alternatives for testing SMTP?

狂风中的少年 提交于 2019-12-21 06:28:39

问题


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?


回答1:


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="me@myorg.com">
        <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.)




回答2:


I would agree with the above...setup your own test SMTP server, and use that for your testing.

Here's some info to get you on the right track:

http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/e4cf06f5-9a36-474b-ba78-3f287a2b88f2.mspx?mfr=true

http://www.cmsconnect.com/praetor/WebHelpG2/Chapter_2_-_Pre-installation_considerations/Configuring_the_SMTP_Server.htm

http://service1.symantec.com/support/ent-gate.nsf/docid/2007241920754398




回答3:


You can save the email to disk:

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



回答4:


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



回答5:


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.



来源:https://stackoverflow.com/questions/2201955/alternatives-for-testing-smtp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!