Testing Zend_Mail

Since I work on a local development machine/server, I’ve never taken the time to set up mail yet, nor do I want to. I think a staging environment is more appropriate to actually have email being sent out. Nevertheless, it has made testing any email functionality a little cumbersome. I’ve done a little research, and have found two ways to tackle the problem. I’ve also included code samples and other resources to get you started.

Create a new mail transport class

Zend has the ability to set a default mail transport class to be used when none is specified, which I’d imagine to be 99% of the time. To set it, all you need to do is put this somewhere early in your application before any mail code is executed.

Zend_Mail::setDefaultTransport(new Site_Mail_Transport_Debug());

The alternative (for the 1% who want to manually specify), you’d simply pass an instance of your mail transport object to Zend_Mail::send() when you call it. What should your class contain? It has to extend Zend_Mail_Transport_Abstract, which at this time of writing this, will specifically need to override the abstract _sendMail() method.

You can use it to create a new record in your database, create a file, or do whatever you need it to. I quickly hacked together one to log it to the database, and based it off of the Sendmail transporter, which is pretty much a wrapper for PHP’s mail function. Here is the code I came up with for those who want some direction. It’s very basic, but should be enough to get you started.

<?php
 
class Site_Mail_Transport_Debug extends Zend_Mail_Transport_Abstract {
 
    public function __construct(Zend_Db_Adapter_Abstract $db) {
        $this->_db = $db;
    }
 
    public function _sendMail() {
        $this->_db->insert(
            'mailtest',
            array(
                'recipients' => $this->recipients,
                'subject'    => $this->_mail->getSubject(),
                'body'       => $this->body,
                'header'     => $this->header
            )
        );
    }
}

Override it at the server level

This is a good idea if you don’t use Zend Framework, or don’t use it for all of your applications. There are two great techniques described on akrabat’s blog. Here they are.

The first, is to override php.ini’s ‘sendmail_path’ and create your own script to handle it. If you were to set it to

sendmail_path = /usr/local/bin/trapmail

then you’d use the following code

formail -R cc X-original-cc 
  -R to X-original-to 
  -R bcc X-original-bcc 
  -f -A"To: [email protected]" 
| /usr/sbin/sendmail -t -i

This requires you to have mail configured on your server, but it still solves the underlying problem of wanting to debug the emails, and also not send out test emails to real users in your application.

The second solution provided is platform independent is for Windows users, and it’s to install fakemail. This program acts as an outgoing mail server, but instead creates files containing any mail passed to it.

Hopefully this helps others out who are also frustrated with dealing with pesky email debugging.