How to Unit Test Sending Mail in Apex

October 15th, 2008

I ran into an issue the other day where I wanted to send out an email notification as part of a trigger. The code itself was no problem but, like most days, my problems began as I tried to write the unit test. I couldn’t get the required test coverage on those lines of code.

<rant>Please Salesforce.com, provide some better documentation on writing test cases. Unit tests are mandatory to deploy Apex to production but the documentation on unit testing is extremely lacking. Everyone on the message boards are screaming this lack of support</rant>.

I contacted our support development rep and he suggested moving the mail functions into their own class and then pass the required parameters to send the mail. This is what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MailerUtils {
 
    public static void sendMail(string message) {
 
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {'me@email1.com','you@email2.com'};
        mail.setToAddresses(toAddresses);
 
        mail.setSubject('My Subject');
 
        mail.setUseSignature(false);
        mail.setHtmlBody(message);
 
        // Send the email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
 
    }   
 
    public static testMethod void testSendMail() {
        sendMail('This is my email message');
    }
 
}

Here is a trigger that would fire after insert and send an email:

1
2
3
4
5
6
7
trigger TestEmail on Contact (after insert) {
 
    for (Contact c : Trigger.new) {
		MailerUtils.sendMail('Welcome ' + c.Name);
    }
 
}

Categories: Apex, Code Sample, Salesforce

Leave a comment

Comments Feed7 Comments

  1. Luke C

    Really? That works as a test method? I thought test methods were supposed to replicate the conditions under which the trigger is fired and test the resulting actions.

  2. jeffdonthemic

    Yes.. believe it or not but that actually works. The external class runs independently but within the same context. The class just need to have code coverage to be deployed. We’ve gone round and round on what exactly code coverage actually means and what it takes to deploy to Production: http://blog.jeffdouglas.com/2009/03/04/how-to-deploy-apex-without-test-coverage/

  3. ben

    The problem though is that I actually want to test the code… It’s easy enough to fake coverage, but not so easy to test email notifications and such.

  4. Unit Testing in Salesforce « Raghusagar’s Blog

    [...] http://blog.jeffdouglas.com/2008/10/15/how-to-unit-test-sending-mail-in-apex/ 37.330836 -121.882733 [...]

  5. Dea

    hi Jeff,

    When you write a test unit, do you have to write one for every trigger seperate? Or can you ‘reference’ all the triggers in that one test unit?

    Thanks in advance

  6. Jeff Douglas

    @Dea, the best practice is to write a single class (marked as @IsTest) for each trigger. This is not required but is best practice. Your test just have to just have to call the appropriate actions and assert that the correct values and/or actions took place.

  7. Thomas Gagne

    I’m looking around for ways to test in-bound message handling–specifically a factory method. I need to construct a Messaging.Email but can’t find any information on its construction except that it doesn’t have a no-parameter constructor.

Leave a comment

Feed

http://blog.jeffdouglas.com / How to Unit Test Sending Mail in Apex

WordPress Appliance - Powered by TurnKey Linux