How to test sending email using MIME::Lite

Earlier this week I had to update a system that uses the MIME::Lite module to send email so that the emails it sends are properly UTF-8 encoded. The change to the code was very simple.

What was a little less simple was writing a test to verify that email is properly encoded. Note that I stated that I was writing a test. When developing software it is not enough to manually test that something does what is expected. We write tests so that we can repeatedly prove that our systems work as they are expected to and also so that we can identify if a later change breaks something.

Thankfully I was programming in Perl which means I had a flexible language to work with. The solution was to redefine MIME::Lite’s send method like so:

no warnings "redefine";
*MIME::Lite::send = *MIME::Lite::as_string;
use warnings "redefine";

What this does is firstly to turn off warnings for redefines. If you use warnings in your Perl programming you will get a runtime warning when you redefine a subroutine or method and we don’t want that warning as we fully intend to do this. Do note that the warnings on redefine are re-enabled immediately once we’re done though.

After we’ve ensured that Perl wont raise a warning we go ahead and redefine the send() method. In this case we redefine it to MIME::Lite’s own as_string method which simply returns the entire email, headers and body, as a single string. The code which calls send() captures the return value and sends it up the calling stack so we will get this back. Even though the code expects to be sending back true or false the fact that Perl doesn’t do strict variable typing means we can do this safely. You can redefine to anything. It’s fairly common to redefine to something as simple as sub { return $_[0] } but in this case MIME::Lite has as_string so we used that.

With this in place I was free to simply call higher level methods in the classes and objects which were in turn using MIME::Lite objects to send email and safely test the resulting emails.

This entry was posted in Code, Email, Perl, Testing. Bookmark the permalink.