-1

I want to write a test class to achieve 100 % code coverage for this below code can anyone help me to solve this problem i don't know how to write a test class for using this trigger

Trigger:

trigger CaseEmail on Case(after insert, after update, before delete) {

    If((Trigger.isUpdate || Trigger.isinsert) && Trigger.isafter) { //This line will allow only if the record is created or edited
        CaseEmailHandler.sendemailforInsrtupdate(Trigger.new);
    }
    if (Trigger.isDelete && Trigger.isBefore) { // if the case is deleted we have to send an email so using this line and we used before because after deletion we cannot send email 
        CaseEmailHandler.sendemailfordelete(Trigger.old);
    }
}

Handler:

public class CaseEmailHandler {

    public static void sendemailforInsrtupdate(List < Case > caselist) {
        Set < Id > conIds = new Set < Id > ();
        List < Messaging.SingleEmailMessage > mails = new List < Messaging.SingleEmailMessage > ();
        for (Case c: caselist) {
            conIds.add(c.ContactId); //adding the contact id so we can get the contact email for the case
        }
        Map < Id, Contact > conMap = new Map < Id, Contact > ([SELECT Id, Email FROM Contact WHERE Id In: conIds]); // quering the contact so we get the contact email

        for (Case c: caselist) {
            if (c.status == 'Closed') { // checking if the status is closed in case of create or edit scenerio
                Contact relatedCaseContact = conMap.get(c.ContactId); //getting the contact information related to particular case

                Messaging.SingleEmailMessage CaseNotificationmail = new Messaging.SingleEmailMessage();
                CaseNotificationmail.setToAddresses(new List < String > {
                    relatedCaseContact.Email
                }); //adding to address
                CaseNotificationmail.setReplyTo('[email protected]'); //adding reply to  address
                CaseNotificationmail.setSenderDisplayName('Salesforce'); //adding display name          

                CaseNotificationmail.setSubject(' Case Status updation  ' + 'Changed to ' + c.status + ' Case Number:' + c.CaseNumber); //adding subject
                CaseNotificationmail.setPlainTextBody(' Your case Status for Case Number: ' + c.CaseNumber + '  Related Case Contact:' + c.ContactId + ' has been closed '); //adding body of the email
                mails.add(CaseNotificationmail); //adding the notification to the list so all the emails can be sent once
            }

            if (Trigger.isinsert && Trigger.isafter) { // as we need a notification when a case is craeted
                Contact relatedCaseContact = conMap.get(c.ContactId);
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                mail.setToAddresses(new List < String > {
                    relatedCaseContact.Email
                });
                mail.setSubject('New Case Create: ' + c.CaseNumber);
                String body = 'Case is created. Thank you for contacting us';
                mail.setHtmlBody(body);
                mails.add(mail);
            }
        }
        Messaging.sendEmail(mails); //sending the emails at once   
    }
    public static void sendemailfordelete(List < Case > caselist) {
        Set < Id > conIds = new Set < Id > ();
        for (Case c: caselist) {
            conIds.add(c.ContactId);
        }
        List < Messaging.SingleEmailMessage > emails = new List < Messaging.SingleEmailMessage > ();
        Map < Id, Contact > conMp = new Map < Id, Contact > ([SELECT Id, Email FROM Contact WHERE Id In: conIds]);

        for (Case cs: caselist) {
            Contact relatedCaseContact = conMp.get(cs.ContactId);
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();

            email.setToAddresses(new List < String > {
                relatedCaseContact.Email
            });
            email.setSubject('Case Deleted');
            email.setPlainTextBody('This message is to alert you that the Case number' + cs.CaseNumber + ' has been deleted. Thank you for contacting us.');
            emails.add(email);
        }
        Messaging.sendEmail(emails);
    }

}
2

3 Answers 3

0

The basic test class should be inserting a Case and updating the case such that the Status field is Closed and Deleting the case to cover 100%. It can be something as below.

        @isTest
    public class CaseEmailHandlerTest {
    @isTest
        public static void  testmethod1(){
            contact con = new contact();
            con.LastName = 'Test contact';
            con.Email = '[email protected]';
            insert con;
            
            Case  cs= new Case();
            cs.Status = 'New';
            cs.Origin = 'Phone';
            cs.ContactId =con.Id;
          
             Test.startTest();
             insert cs;   
             cs.status='Closed';
             update cs;
             delete cs;
            Test.stopTest();
    
        }
}

But the main part of your code is sending an email when the case is created or update or deleted so you have to check if emails were being sent or not using email Invocations.

so the test class should be as below.

   @isTest
public class CaseEmailHandlerTest {
@isTest
    public static void  testmethod1(){
        contact con = new contact();
        con.LastName = 'Test contact';
        con.Email = '[email protected]';
        insert con;
        
        Case  cs= new Case();
        cs.Status = 'New';
        cs.Origin = 'Phone';
        cs.ContactId =con.Id;
      
         Test.startTest();
          insert cs;
        Integer emailInvocations = Limits.getEmailInvocations();
    Test.stopTest();

    system.assertEquals(1, emailInvocations, 'An email should be sent');
       

    }
    
    @isTest
    public static void testmethod2(){
        contact con = new contact();
        con.LastName = 'Test';
        con.Email = '[email protected]';
        insert con;
        
        Case cs = new Case();
        cs.Status = 'New';
        cs.Origin = 'Phone';
        cs.ContactId =con.Id;
      insert cs;
         Test.startTest();
           cs.status='Closed';
        update cs;
        delete cs;

        Integer emailInvocations = Limits.getEmailInvocations();
    Test.stopTest();

    system.assertEquals(2, emailInvocations, 'An email should be sent');
        

    }
}

You also need to add the negative scenario by updating the case status to some other and check if the email is not sent .

4
  • Hi Sai , in above code test method1 is executing perfectly but second method won't be work for update and delete Apr 26, 2022 at 9:45
  • @can you confirm what do you meant by not working. Is it not covering or are you facing any issue in it. Apr 26, 2022 at 9:51
  • I got the problem I solved it Thanks Apr 26, 2022 at 10:15
  • hy , i'm inserting a bulk of data of 200 records in test class of case can you tell me where i'm doing wrong it showing error:- inserted failed Apr 26, 2022 at 10:17
0

Something like below should work.

@isTest
public class CaseEmailHandlerTest {
    @testSetup
    public static void setup(){
        contact con = new contact();
        con.LastName = 'Test';
        con.Email = '[email protected]';
        insert con;
        
        Case newCase = new Case();
        newCase.Status = 'New';
        newCase.Origin = 'Phone';
        newCase.ContactId =con.Id;
        insert newCase;
        
        Case closedCase = new Case();
        closedCase.Status = 'Closed';
        closedCase.Origin = 'Phone';
        closedCase.ContactId =con.Id;
        insert closedCase;
    }
    
    @isTest
    public static void testSendemailforInsrtupdate(){
        List<Case> caselist = [SELECT Id,CaseNumber,Status,ContactId,ContactEmail FROM Case];
        CaseEmailHandler.sendemailforInsrtupdate(caselist);
        //Add Assert statement here
    }
    
    @isTest
    public static void testSendemailfordelete(){
        List<Case> caselist = [SELECT Id,CaseNumber,ContactId,ContactEmail FROM Case];
        CaseEmailHandler.sendemailfordelete(caselist);
        //Add Assert statement here
    }
}
0

As the platform does not supply mocking for email sends, you have to use code like this to assert what has been sent in your test cases:

public class CaseEmailHandler {

    // Test cases can assert what is sent by referencing this
    @TestVisible private List<Messaging.SingleEmailMessage> sentMails
            = List<Messaging.SingleEmailMessage>();

    ...


    // Code that wants to send calls this
    private static void sendEmail(List<Messaging.SingleEmailMessage> mails) {
        if (!Test.isRunningTest()) Messaging.sendEmail(mails); 
        else sentMails.addAll(mails);
    }
}
2
  • I'd advise against this, because you're not going to get 100% coverage, and you're mixing in test code with live code. An DI-based solution would be better.
    – sfdcfox
    Apr 24, 2022 at 16:49
  • Hi @sfdcfox, Sure modifying the live code is not ideal, but doesn't a DI solution amount to the same thing just done with more lines of code?
    – Keith C
    Apr 24, 2022 at 19:41

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