Fake a SMTP Server with Python for Rails Testing
So I’ve been in the process of writing an integration test to verify the flow of registration through some unique conditions. One thing I ran into while writing my Rails test was this error.
Connection refused – connect(2) for nil port 25
After looking around at documentation on what to do for testing it seemed that everything was as it should be except my test environment wasn’t bypassing the actual sending of email which lead to this error. Since I couldn’t find the answer with any Rails, S.O., or github.com/mikel/mail documentation on a quick fix I decided to use a dummy SMTP server.
I didn’t want to keep any mail sent, so this question http://serverfault.com/questions/207619/how-to-setup-a-fake-smtp-server-to-catch-all-mails had an excellent answer with Python. It seems Python has a smtpd debugging feature which just prints incoming SMTP email out to STDOUT.
sudo python -m smtpd -n -c DebuggingServer localhost:25
Now I don’t want to have to type this every time I run my Rails test suite so I need to have my computer start with this running in the background. On Ubuntu that was rather simple to do by creating a text file in /etc/init.d , making it executable, and adding it to the boot-up sequence with update-rc.d . Since I don’t care about looking at the email I’ve routed the output to /dev/null. But you could just as easily append it to a text file to read periodically.
sudo echo "python -m smtpd -n -c DebuggingServer localhost:25 > /dev/null 2>&1 &" > /etc/init.d/fake-smtp sudo chmod +x /etc/init.d/fake-smtp sudo update-rc.d fake-smtp defaults
You may get a message complaining about invalid header information. But that’s not important as your background task will still start up on boot. And even though it won’t shutdown properly through this script, the computer will be turning off anyways so that will close it.
And now my Rails test passes splendidly. If you’d like to start the script without rebooting just type:
sudo /etc/init.d/fake-smtp start
If you want to write to a text file just change /dev/null to the path and file you want written to. If you want it to append to the text file and not overwrite then change the preceding greater than symbol to two greater than symbols >>.
I’m quite happy that Python has included this debugging tool as it allows me a no hassle use as I don’t have to install anything or worry about any file clutter.
-Daniel P. Clark