3

Trigger is:

trigger emailtemplate on opportunity(after update)
{
          List<opportunity> oList = Trigger.new;
          List<opportunity> nList = trigger.old;

          if(oList[0].StageName != nList[0].StageName)
          { 

              Set<Id> opportunityIds= new Set<Id>(); 

              user u=[select id,email from user where id=: UserInfo.getUserId()];

              Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage();
              mail.setToAddresses(new String[] { ''+u.email });
              mail.setSubject('Reg:opporunity stage update:'+' User: '+UserInfo.getUserName());
              mail.setHtmlBody('new value is:  '  + oList[0].StageName +  ',   old value is:  '  + nList[0].StageName);
              mail.setUseSignature(true);
              Messaging.sendEmail(new Messaging.SingleEmailMessage[]{mail});
           }
}
1
  • Note that triggers that send SingleEmailMessage can run into governor limits as the trigger runs as a batch - you should be checking to see that you haven't exceeded daily outbound email limit within the trigger and consider alternatives such as using sobject fields to hold the cponstructed message and a workflow w/ email alert to execute the email.
    – cropredy
    Oct 29, 2014 at 18:16

2 Answers 2

9

By design, Salesforce will not send any outbound email while executing tests. This is to prevent you from accidentally spamming people (or yourself) during tests. This does however make it difficult to properly test your code as it is best practice to not test for code coverage, but for all logical branches.

The way that I have worked around this is to separate the construction of the email into a separate class that returns a SingleEmailMessage. This way I can still write my test methods to check that the body was constructed as expected as well as the other properties of the email. You can use assertions to check the body, subject, To Address, etc.

While this still doesn't allow you to test and verify an email was actually sent, it does allow you to verify that everything about the email is as you expect, given the input parameters, prior to sending.

Here is some Psuedo Code to illustrate

Call a utility class to construct the email. (you will have to create the class to use the input and create and return the SingleEmailMessage.)

trigger emailtemplate on opportunity(after update){

    List<opportunity> oList = Trigger.new;
    List<opportunity> nList = trigger.old;

    if(oList[0].StageName != nList[0].StageName){ 

        Set<Id> opportunityIds= new Set<Id>(); 

        user u=[select id,email from user where id=: UserInfo.getUserId()];

        Messaging.SingleEmailMessage mail = MailUtility.constructEmail(u.Email, UserInfo.getUserName(), oList[0].StageName, nList[0].StageName);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[]{mail});
    }
}

Now in your test code, you can test that method of the utility class to verify the attributes of the SingleEmailMessage. Something like this

SingleEmailMessage myMail = MailUtility.constructEmail(some_email_address, some_user_name, some_stage_name, another_stage_name);

system.assertEquals(myMail.HTMLBody, "your expected body");
system.assertEquals(myMail.Subject, "your expected subject");
.........
1
  • Chris -- worth noting that while you can't assert whether email was sent outwards from SFDC, you can assert whether sendEmail(..) was invoked by comparing the value of Limits.getEmailInvocations() before and after the method under test.
    – cropredy
    Oct 21, 2016 at 23:38
0

Insert an Opportunity record in test method, change the StageName field value and update the record.Thats it.Your trigger will get fired.

1
  • This gives you code coverage only. It is always best practice to test far beyond code coverage. Oct 29, 2014 at 11:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .