You need to sign in to do that
Don't have an account?
Developer.mikie.Apex.Student
Help writing Test code for Email trigger and class and cleaning up redundant code
Hey there,
I have an email trigger and a class in which I use to send emails to all the contacts associated with an account when a service (which is also associated with the account) reaches stage 4. I have written test codes before, but I do not even know where to begin to write test code for an email trigger. please help.
This is my trigger:
trigger SendEmailtocontact on Service__c (after Update) {
List<String> lcontactEmails = new List<String>();
Set<Id> sIds = new Set<Id>();
for(Service__c qItr : Trigger.new){
if(Trigger.isUpdate){
if(Trigger.oldmap.get(qItr.id).Service_Stage__c != qItr.Service_Stage__c && qItr.Service_Stage__c.containsIgnoreCase('Stage 4')){
sIds.add(qItr.id);
}
}
else if(Trigger.isInsert){
if(Trigger.newMap.get(qItr.id).Service_Stage__c.containsIgnoreCase('Stage 4')){
sIds.add(qItr.id);
}
}
}
for(Account accItr : [SELECT id,(SELECT id FROM Contacts) FROM Account WHERE id IN (SELECT Account__c FROM Service__c WHERE Id IN: sIds)]){
for(Contact con : accItr.contacts){
if(!String.isBlank(con.id)){
lcontactEmails.add(con.id);
}
}
if(!lcontactEmails.isEmpty()){
EmailHandler.sendEmail(lcontactEmails);
}
}
}
This is my class:
public class EmailHandler{
public static void sendEmail (List<String> contactids){
Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
//set the email properties
mail.setTargetObjectIds(contactids);
mail.setSenderDisplayName('Destiny Customer Service');
mail.setTemplateId('00XO0000000MEyP'); //Id of the Email Template
//send the email
Messaging.sendEmail(new Messaging.MassEmailMessage[] { mail } );
}
}
I was also hoping to maybe get some pointers on how I may clean up this code a bit, as I changed it a bit and I am sure there is a fair bit of redundant lines in there.
Thank you in advance for your help
Kind regards,
Mikie
I have an email trigger and a class in which I use to send emails to all the contacts associated with an account when a service (which is also associated with the account) reaches stage 4. I have written test codes before, but I do not even know where to begin to write test code for an email trigger. please help.
This is my trigger:
trigger SendEmailtocontact on Service__c (after Update) {
List<String> lcontactEmails = new List<String>();
Set<Id> sIds = new Set<Id>();
for(Service__c qItr : Trigger.new){
if(Trigger.isUpdate){
if(Trigger.oldmap.get(qItr.id).Service_Stage__c != qItr.Service_Stage__c && qItr.Service_Stage__c.containsIgnoreCase('Stage 4')){
sIds.add(qItr.id);
}
}
else if(Trigger.isInsert){
if(Trigger.newMap.get(qItr.id).Service_Stage__c.containsIgnoreCase('Stage 4')){
sIds.add(qItr.id);
}
}
}
for(Account accItr : [SELECT id,(SELECT id FROM Contacts) FROM Account WHERE id IN (SELECT Account__c FROM Service__c WHERE Id IN: sIds)]){
for(Contact con : accItr.contacts){
if(!String.isBlank(con.id)){
lcontactEmails.add(con.id);
}
}
if(!lcontactEmails.isEmpty()){
EmailHandler.sendEmail(lcontactEmails);
}
}
}
This is my class:
public class EmailHandler{
public static void sendEmail (List<String> contactids){
Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
//set the email properties
mail.setTargetObjectIds(contactids);
mail.setSenderDisplayName('Destiny Customer Service');
mail.setTemplateId('00XO0000000MEyP'); //Id of the Email Template
//send the email
Messaging.sendEmail(new Messaging.MassEmailMessage[] { mail } );
}
}
I was also hoping to maybe get some pointers on how I may clean up this code a bit, as I changed it a bit and I am sure there is a fair bit of redundant lines in there.
Thank you in advance for your help
Kind regards,
Mikie
Hi,
Try the below modified code (In Bold)
//////////////// Test class ///////////////////
@istest
private class SendEmailtocontact {
static testMethod void SendEmailtocontact()
{
account a1=new account(name='test');
insert a1;
contact con=new contact(lastname='con',firstname='test',email='test@gmail.com',accountid=a1.id);
insert con;
Service__c serviceobj=new Service__c(Service_Stage__c='Stage 1',Account__c=a1.id);
insert serviceobj;
serviceobj.Service_Stage__c='Stage 4';
update serviceobj;
}
}
In previous Test Class I haven't passed the account id for the contact that's why the EmailHandler desn't executed as the contact list was null.
Try the above one and I am sure that you will get 100% from Email Handler and more than 90% for trigger .
All Answers
Try the below modified code
trigger SendEmailtocontact on Service__c (after Update)
{
List<String> lcontactEmails = new List<String>();
Set<Id> sIds = new Set<Id>();
//Added
Set<ID> accIds = new Set<ID>();
for(Service__c qItr : Trigger.new)
{
if(Trigger.isUpdate)
{
if(Trigger.oldmap.get(qItr.id).Service_Stage__c != qItr.Service_Stage__c && qItr.Service_Stage__c.containsIgnoreCase('Stage 4'))
{
sIds.add(qItr.id);
//Added
accIds.add(qItr.Account__c);
}
}
//Will Never Execute as trigger will fire only if a record is updated
else if(Trigger.isInsert)
{
if(Trigger.newMap.get(qItr.id).Service_Stage__c.containsIgnoreCase('Stage 4'))
{
sIds.add(qItr.id);
}
}
}
// Modified
//for(Account accItr : [SELECT id,(SELECT id FROM Contacts) FROM Account WHERE id IN (SELECT Account__c FROM Service__c WHERE Id IN: sIds)])
for(Account accItr : [SELECT id,(SELECT id FROM Contacts) FROM Account WHERE id IN : accIds])
{
for(Contact con : accItr.contacts)
{
if(!String.isBlank(con.id))
{
lcontactEmails.add(con.id);
}
}
// No need to put this condition here.
/*if(!lcontactEmails.isEmpty())
{
EmailHandler.sendEmail(lcontactEmails);
}*/
}
//Put this here
if(!lcontactEmails.isEmpty())
{
EmailHandler.sendEmail(lcontactEmails);
}
}
//////////////// Test class ///////////////////
//Below is the test class sample code.please modified as per your requirment and datamodel
// This will execute your trigger logic and the EmailHandler class logic
@istest
private class SendEmailtocontact {
static testMethod void SendEmailtocontact()
{
account a1=new account(name='tes');
insert a1;
contact con=new contact(lastname='con',firstname='test',email='test@gmail.com');
insert con;
Service__c serviceobj=new Service__c(Service_Stage__c='Stage 1',Account__c=a1.id);
insert serviceobj;
serviceobj.Service_Stage__c='Stage 4';
update Service_Stage__c;
}
}
Hey Ankit,
Thank you so much for your help. I am very impressed with your ability to analyze and write something like that so fast. I imput your trigger and it still works perfectly so thankyou. The test saved aswell after I changed the -update service_stage__c- to -Update serviceobj-.
However, upon running the test, although i got a pass I was left with a code coverage of 64% in the trigger and 0 in the emailhandler class. You mentioned that i would have to modify as per requirements of my data model. Would you be able to give me an example of what i need to do to get 100%?
Once again thank you so much for your time.
Hi,
Try the below modified code (In Bold)
//////////////// Test class ///////////////////
@istest
private class SendEmailtocontact {
static testMethod void SendEmailtocontact()
{
account a1=new account(name='test');
insert a1;
contact con=new contact(lastname='con',firstname='test',email='test@gmail.com',accountid=a1.id);
insert con;
Service__c serviceobj=new Service__c(Service_Stage__c='Stage 1',Account__c=a1.id);
insert serviceobj;
serviceobj.Service_Stage__c='Stage 4';
update serviceobj;
}
}
In previous Test Class I haven't passed the account id for the contact that's why the EmailHandler desn't executed as the contact list was null.
Try the above one and I am sure that you will get 100% from Email Handler and more than 90% for trigger .
100% on class and 82% on trigger. You are a lifesaver.