6

How could I write unit tests for the SendEmailResult. I want to generate erros in to errResult parameter. What are the possible ways of testing this.

        Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();

        message.setSubject('failed');
        message.setToAddresses(new String[] { UserInfo.GetUserId() });
        message.setHtmlBody('Something');

        Messaging.SingleEmailMessage[] errMessages = new List<Messaging.SingleEmailMessage> { message };
        **Messaging.SendEmailResult[] errResults = Messaging.sendEmail(errMessages);**
5

This is fun question! I've tried to noodle this a few different ways and show examples of developer-friendly test cases. But I confess: there is the possibility it will be a frustrating job in real orgs:

  • in Sandboxes, the Email Deliverability setting might mean NO emails can ever be sent
  • the "breaking mutation" made in the test case may not reflect the actual real world exception

But it's still always good to aspire to meaningful test cases and testable code :-)

We can go all-out and use an interface to allow mock injection etc. Or use Test.isRunningTest in the code to pervert the execution. Or just expose some properties for the test to modify, for example:

//this property allows the test to mess with the email 
@TestVisible static Messaging.SingleEmailMessage Message = new Messaging.SingleEmailMessage();

/**
 * Code under test
 */
static public void sendEmail() {
    message.setTargetObjectId(UserInfo.getUserId());
    message.setSaveAsActivity(false);
    message.setSubject('dear diary');
    message.setPlainTextBody('he who controls the spice');
    Messaging.sendEmail(new List<Messaging.Email>{Message});
}

Negative test case:

  • if the code doesn't throw an exception, we hear about it!
  • we make some assertion that the exception is the type we want,

static testmethod void testEmailFailureThrowsException() {
    //arrange (intended to break email)
    Message.setTemplateId('a01000000000bad');

    try {
        //act
        sendEmail();
        System.assert(false, 'exception expected');

    } catch (Exception e) {
        //assert
        String expectedTypeName = 'System.EmailException';
        String actualTypeName = e.getTypeName();
        System.assertEquals(expectedTypeName, actualTypeName, 'wrong exception type name');
    }
}

Positive test case

  • the act is naked (no try-catch), if it fails we'll hear about it!
  • using the Limits class allows us to spy on the actual email side effect

static testmethod void testEmailSuccessIncursInvocation() {
    //assert before
    Integer expectedLimits = 0;
    Integer actualLimits = Limits.getEmailInvocations();
    System.assertEquals(expectedLimits, actualLimits, 'wrong limits before');

    //act
    sendEmail();

    //assert after
    expectedLimits = 1;
    actualLimits = Limits.getEmailInvocations();
    System.assertEquals(expectedLimits, actualLimits, 'wrong limits after');

}
| improve this answer | |

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.