Was trying to use SingleEmailMessage to send email when a apex test method is invoked, but seems like it does not work. When same code is executed via anonymous apex block it works fine. Any limitation which I am not aware about ?

public class TestClass {

    public static void sendEmail(){
        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
        message.toAddresses = new String[] { 'xyz@force.com' };
        //message.optOutPolicy = 'FILTER';
        message.subject = 'Opt Out Test Message';
        message.plainTextBody = 'This is the message body.';
        Messaging.SingleEmailMessage[] messages = 
        new List<Messaging.SingleEmailMessage> {message};
         Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);
  • Tests do not send emails. There have been bugs that broke that pattern, but it is not supposed to be allowed. Is that behavior you are expecting or hoping for? Your tests should have no persistent effects. That's one of their driving principles. – Adrian Larson Feb 16 '17 at 21:28
  • I do believe that email service do not work in Test Classes.. Am I missing something here – Reddy Feb 16 '17 at 21:40

Unit test methods take no arguments send no emails. See the Apex Developer Guide (emphasis added):

What are Apex Unit Tests?

To facilitate the development of robust, error-free code, Apex supports the creation and execution of unit tests. Unit tests are class methods that verify whether a particular piece of code is working properly. Unit test methods take no arguments, commit no data to the database, send no emails, and are flagged with the testMethod keyword or the isTest annotation in the method definition. Also, test methods must be defined in test classes, that is, classes annotated with isTest.


In addition to Adrians explanation as to "What are Apex Unit Tests", I feel a short sample of how you can test the email functionality you implemented would be helpful. We can inspect the number of email invocations (such as sendEmail) that have been called within the context of a single test method.

Integer invocations = Limits.getEmailInvocations(); 

Limit information will now be returned to our invocations variable.

static testmethod void singleEmailInvocation(){
        Integer invocations = Limits.getEmailInvocations();
        system.assertEquals(1, invocations, '1 email should be sent');

In the above code snippet, I am calling a EmailSender class that has a single method performing the same logic you have included in your question. A single email is sent per call to sendEmail(). We expect invocations to be 1 for each call. We can bulk test this by using the following.

static testmethod void bulkEmailInvocation(){
        for (Integer i=0; i<10; i++) EmailSender.sendEmails();
        Integer invocations = Limits.getEmailInvocations();
        system.assertEquals(10, invocations, '10 emails should be sent');
  • I had thought of adding that but didn't get around to it. Glad to see it posted here! – Adrian Larson Feb 17 '17 at 0:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.