0

Now I have 0% coverage.

    System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, CaseHandlerCountAlert: execution of AfterInsert

caused by: System.EmailException: SendEmail failed. First exception on row 0; first error: INVALID_EMAIL_ADDRESS, Email address is invalid: null: [toAddresses, null]

Trigger.CaseHandlerCountAlert: line 78, column 1: []

My Trigger sends an email message when an Account has 8 cases created within 7 days. The Case object has a Lookup relationship to the Milestone1__project__c object has a relationship name Parent_Project_If_Applicable__r. If any of these fields are equal to 'Live - Closed Project':

Parent_Project_if_applicable__r.Implementation_status__c Parent_Project_if_applicable__r.PM_Implementation_Status__c Parent_Project_If_Applicable__r.RCM_Implementation_Status__c

THen the Email is sent to the address in the IF BLock. Any other value the email is sent through the Else Block.

Every test pass except setup. I am trying to create a user (preferably two) with email addresses. I found that the fields Parent_Project_if_applicable__r.Resource_Coordinator_Email__c and Parent_Project_if_applicable__r.Client_Advisor_Email__c are formula fields grabbing the email in a formula that looks like this Client_Advisor__r.Email and Resource_Coordinator_Email__c .
How do I add Insert the user so that I can test that the emails would go to the right destination?

Test Class:

    @isTest
private class TestCaseHandlerAlert {

    @TestSetup static void setup(){
       //Create user to populate field Resource Coord. and Implementation Spec.

        Profile p = [SELECT Id FROM Profile WHERE Name='Standard User']; 
        User u = new User(Alias = 'testER', Email='[email protected]', 
            EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
            LocaleSidKey='en_US', ProfileId = p.Id, 
            TimeZoneSidKey='America/Los_Angeles', UserName='[email protected]');

        insert u;
        system.debug(u.email);

       // Create and Insert 2 Accounts

        Account a = new Account();
        Account b = new Account();
            a.name = 'testacct21';
            b.name = 'testacct31';



 //Set Contact id to variables
 //  Id userIDToInsert = [select id from User Where username='[email protected]'].id;


  // Create Milestones

 //This Milestone will fire the If Block    
  Milestone1_Project__c project1 = new Milestone1_Project__c();
        project1.Name = 'triggertestLIVE';
        project1.RCM_Implementation_Status__c = 'LIVE - CLOSED PROJECT';
        project1.PM_Implementation_Status__c= 'RETURNED SOFTWARE';
        project1.Implementation_Status__c= 'RETURNED SOFTWARE';
        project1.Resource_Coordinator__c = u.Id;
        project1.Client_Advisor__c = u.Id;


 Milestone1_Project__c project = new Milestone1_Project__c();
        project.Name = 'triggertest21';
        project.RCM_Implementation_Status__c = 'RETURNED SOFTWARE';
        project.PM_Implementation_Status__c= 'RETURNED SOFTWARE';
        project.Implementation_Status__c= 'RETURNED SOFTWARE';
        project1.Resource_Coordinator__c = u.Id;
        project1.Client_Advisor__c = u.id;


     //Insert Account
    insert a;
    insert b;
    //Insert Project
    insert project;
    insert project1;

    //Create 10 Cases associated with Project

    List<Case> casesToInsert = new List<Case>();
    List<Case> casesToInsert1 = new List<Case>();

        for (Integer i=1; i<10; i++){

            Case c = new Case();
                c.AccountId = a.id;
                c.Origin = 'Phone';
                c.Impact__c = 'Low';
                c.Severity__c = 'Minor';
                c.Type = 'Bridge';
                c.Parent_Project_if_applicable__c = project1.id;

            casesToInsert.add(c);
         }

        for (Integer i=1; i<10; i++){  
        Case c1 = new Case();
        c1.AccountId = b.id;
        c1.Origin = 'Phone';
        c1.Impact__c = 'Low';
        c1.Severity__c = 'Minor';
        c1.Type = 'Bridge';
        c1.Parent_Project_if_applicable__c = project.id;

        casesToInsert.add(c1);
    }          



      insert casesToInsert; 
      insert casesToInsert1;

    }



@isTest static void DontSendNotLimit (){
        // Do not send, not enough Cases need 8 
        List<Case> testCases = [SELECT Id FROM Case WHERE Account.Name='testacct21' LIMIT 5];
        List<Case> insertCases = new List<Case>();   

      Test.startTest();
        insert insertCases;
        System.debug('Should be 0 emails sent: ' + Limits.getEmailInvocations());
      Test.stopTest();
    }

@isTest static void SendElseBlock (){
        // Else BLock Fires - 2 emails sent 
        List<Case> testCases = [SELECT Id FROM Case WHERE Account.Name='testacct21' LIMIT 8];
        List<Case> insertCases = new List<Case>();   

      Test.startTest();
        insert insertCases;
        System.debug('Should be 3: ' + Limits.getEmailInvocations());
      Test.stopTest();
    }   



@isTest static void SendRCMiFBlock (){
        // Fires the If BLock 1/3
        List<Case> testCases = [SELECT Id FROM Case WHERE Account.Name='testacct31' LIMIT 8];
        List<Case> insertCases = new List<Case>();  
        for(Case cas :testCases ){

                insertCases.add(cas);
            } 

      Test.startTest();
        insert insertCases; 
      Test.stopTest();
    }

    @isTest static void SendPMiFBlock (){
        // Fires the If BLock 2/3
        List<Case> testCases = [SELECT Id FROM Case WHERE Account.Name='testacct31' LIMIT 8];
        List<Case> insertCases = new List<Case>();  
        for(Case cas :testCases ){

                cas.Parent_Project_if_applicable__r.PM_Implementation_Status__c = 'LIVE - CLOSED PROJECT';
                insertCases.add(cas);
            } 

      Test.startTest();
        insert insertCases; 
      Test.stopTest();
    }

    @isTest static void SendIMPiFBlock (){
        // Fires the If BLock 3/3
        List<Case> testCases = [SELECT Id FROM Case WHERE Account.Name='testacct31' LIMIT 8];
        List<Case> insertCases = new List<Case>();  
        for(Case cas :testCases ){
                cas.Parent_Project_if_applicable__r.Implementation_Status__c= 'LIVE - CLOSED PROJECT';
                insertCases.add(cas);
            } 

      Test.startTest();
        insert insertCases; 
      Test.stopTest();
    }


}

Trigger:

trigger CaseHandlerCountAlert on Case (after insert, after update) {

//Case trigger that will send email alert when 8 cases are created within 7 days.
String messageToSend;
List <String> ListOfMessages = new List <String>();
Set <Id> AcctIds = new Set <Id>();
String messageBody;

List < AggregateResult > AggregateResultList = [SELECT AccountId, Account.Name name, COUNT(Id) co
                                                FROM Case
                                                WHERE CreatedDate = LAST_N_DAYS:7 AND Id IN :Trigger.New
                                                GROUP BY AccountId, Account.Name
                                                HAVING COUNT(Id) >= 8
                                               ];

Map < Id, String > accountIdEmailmessageMap = new Map < Id, String > ();

for (AggregateResult aggr: AggregateResultList) {
    String messageToSend = 'Account name: ' + aggr.get('name') +
        ' has ' + (Integer) aggr.get('co') +
        ' cases opened in the last 8 days.';
    Id accId = (Id) aggr.get('AccountId');
    accountIdEmailmessageMap.put(accId, messageToSend);
    AcctIds.add(accId);
}


List < Case > caseList = [SELECT Id, AccountId, Account.Name, Parent_Project_if_applicable__r.Implementation_status__c,
                          Parent_Project_if_applicable__r.PM_Implementation_Status__c,
                          Parent_Project_if_applicable__r.RCM_Implementation_Status__c,
                          Parent_Project_if_applicable__r.Resource_Coordinator_Email__c,
                          Parent_Project_if_applicable__r.Client_Advisor_Email__c                      
                          FROM Case
                          WHERE AccountId IN: AcctIds];

List<Messaging.SingleEmailMessage> lstASingleEmailMessage = new List<Messaging.SingleEmailMessage>();
List<Messaging.SingleEmailMessage> lstBSingleEmailMessage = new List<Messaging.SingleEmailMessage>();

for (Case cl: caseList) {

    if (cl.Parent_Project_if_applicable__r.Implementation_status__c == 'Live - Closed Project' ||
        cl.Parent_Project_if_applicable__r.PM_Implementation_Status__c == 'Live - Closed Project' ||
        cl.Parent_Project_If_Applicable__r.RCM_Implementation_Status__c == 'Live - Closed Project') {

            String messageBody = accountIdEmailmessageMap.get(cl.AccountId);

            List<String> emailaddr = new List<String>();
            emailaddr.add('[email protected]');  

            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
            mail.setSenderDisplayName('Support');
            mail.setToAddresses(emailaddr);   
            mail.Subject = 'Multiple cases created alert message';
            mail.setPlainTextBody(messageBody);
            lstASingleEmailMessage.add(mail);




        }else{
            String messageBody1 = accountIdEmailmessageMap.get(cl.AccountId);        

            List<String> emailAdds = new List<String>();
            emailAdds.add(cl.Parent_Project_if_applicable__r.Resource_Coordinator_Email__c);
            emailAdds.add(cl.Parent_Project_if_applicable__r.Client_Advisor_Email__c); 

            Messaging.SingleEmailMessage amail = new Messaging.SingleEmailMessage();
            amail.SetSenderDisplayName('Support');
            amail.setToAddresses(emailAdds);
            amail.Subject = 'Multiple cases created alert message';
            amail.setPlainTextBody(messageBody1);
            lstBSingleEmailMessage.add(amail);


        }  
}
Messaging.SendEmailResult[] r = Messaging.sendEmail(lstASingleEmailMessage);   
Messaging.SendEmailResult[] rb = 

Messaging.sendEmail(lstBSingleEmailMessage);
}
2
  • please use edit and a) identify the line in the code where the error is reported. And, include the full stacktrace you are getting.
    – cropredy
    Nov 11, 2019 at 23:38
  • Please edit your post to callout which line is line 17. Nov 12, 2019 at 1:47

1 Answer 1

0

Your tests are passing with false positives because your setup() method is not annotated correctly with the @testSetup annotation. That annotation is required to make the test setup method run prior to each unit test; otherwise, it's just an ordinary unit test itself, whose data-creation steps are not applied to the context of each other test within the class.

Take this example:

@isTest static void SendRCMiFBlock (){
        // Fires the If BLock 1/3
        List<Case> testCases = [SELECT Id FROM Case WHERE Account.Name='testacct31' LIMIT 8];

This query returns an empty list.

        List<Case> insertCases = new List<Case>();  
        for(Case cas :testCases ){

                insertCases.add(cas);
            } 

This for loop never executes because testCases is empty.

      Test.startTest();
        insert insertCases; 

This insert DML does nothing because insertCases is empty

      Test.stopTest();
    }

And you get a false positive here because no assertions are made. This is a great illustration of why tests must assert against behavior. Your results are valueless if they only show that the code does not crash: you need to demonstrate that it behaves as you believe it behaves.

Setup Problems

    User u = new User(Alias = 'testER', Email='[email protected]', 
        EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
        LocaleSidKey='en_US', ProfileId = p.Id, 
        TimeZoneSidKey='America/Los_Angeles', UserName='[email protected]');

This is likely to cause failures. UserName must be globally unique, across all Salesforce orgs. A common strategy to ensure this is to concatenate a unique token for your project with something like DateTime.now().getTime().

Id userIDToInsert = [select id from User Where username='[email protected]'].id;

You don't need to do this. The Id is populated in u after insert. Just use u.Id.

Failure

The line you've identified as the source of the problem is not data-dependent. It uses a single, hard-coded email address in the code as written. For that reason, I'm a little skeptical that that's the true problem. I would recommend correcting the issue with the setup annotation and trying again; doing so may reveal the genuine source of your issues.

5
  • Thank you. My @testSetup is notated correctly now, but I am still receiving the above errors. I'm just not understanding how to create a user and then apply that user id to a field in the testSetup method.
    – Tim
    Nov 12, 2019 at 3:47
  • @Tim you don't need to iteratively update your question with new versions of your code. This makes your question and the answers received difficult to follow for other contributors. Additionally, removing the trigger code means I can't really follow up on this comment.
    – David Reed
    Nov 12, 2019 at 3:58
  • my apologies. I am still learning the platform. I have added my code for the Trigger back into the question.
    – Tim
    Nov 12, 2019 at 8:30
  • I don't have an answer for you as to the root cause based on reading your code. I'd factor out a lot of the data setup into the test methods that intend to use it, add some logging, and see what details you can figure out about the data state as you move through your tests.
    – David Reed
    Nov 12, 2019 at 20:09
  • Factoring out data setup into the methods sounds like a plan. I'll try that. Thank you.
    – Tim
    Nov 12, 2019 at 20:56

You must log in to answer this question.

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