+ Start a Discussion
Patrick G. BrownPatrick G. Brown 

Help with Test Class to test Trigger Validation on Delete

I have a trigger that looks to see if a Campaign is Active and if so, throws an error when a user tries to delete it.  Here is my trigger:
 
trigger cannotDeleteCampaignMember on CampaignMember (before delete) {
    if(System.Trigger.IsDelete){
        Set<Id> leadIds = new Set<Id>();
        for (CampaignMember cm: Trigger.old){
            leadIds.add(cm.LeadId);
        }
        Map<Id, Lead> leadMap = new Map<Id, Lead>([SELECT Id, Current_Campaign__c, Status FROM Lead WHERE Id IN :leadIds]);
        List<Lead> leadToUpdate=new List<Lead>();
        for (CampaignMember cm: Trigger.old)
        {Lead associatedLead = leadMap.get(cm.LeadId);
         if(associatedLead.Current_Campaign__c!=null)
         {
             cm.adderror('Only the Marketing Team can delete Campaign Members.  If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first.');
         }
         if(associatedLead.Current_Campaign__c==null)
         {
             associatedLead.Status = 'Resting';
             leadToUpdate.add(associatedLead);
         }
         
        } 
        update leadToUpdate;
    }   
}

I've written a test class that meets the threshold of passing, so I'm good to move my code to our Production org.  However, the way I would like to test this isn't working the way one would expect.  Here is my test class:
 
@isTest

public class testCannotDeleteCampaignMember {
    @isTest
    public static void runTestDelete(){
        String campName4 = 'Apex Test Campaign4';  
        String lead4firstName = 'Apex4';
        String lead4lastName = 'Test4';
        String lead4Company = 'Apex Test Company4';
        
        
        //Create Campaign1
        Campaign camp4 = new Campaign(Name=campName4, Isactive=True);
        insert camp4;
        
        
        // Create Lead 1
        Lead lead4 = new Lead(firstName=lead4firstName,
                              lastName=lead4lastName,
                              Company=lead4Company);
        insert lead4;
        
        
        //Grab Campaign ID for the Campaigns created above
        
        Campaign campid4 = [SELECT Id FROM Campaign WHERE Name = 'Apex Test Campaign4' LIMIT 1];
        
        // Associate Lead 1 to Campaign - You must deactivate Activate Campaign on Create WFR
        CampaignMember newMember4 = new CampaignMember(LeadID = lead4.Id, 
                                                       status='Sent',
                                                       campaignid = campid4.id);
        insert newMember4;
        
        
        CampaignMember deletedCM = [SELECT Id, IsDeleted FROM CampaignMember WHERE campaignid = :campid4.id ALL ROWS];
        //Try to delete the Campaign Member        
        try
        {
            
            delete newMember4;
        }
        
        //Validate error is thrown
        catch(Exception e)
        {
            System.Assert(e.getMessage().contains('Only the Marketing Team can delete Campaign Members. If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first.'));
        }
    }
}

When I run this test class it fails every time in row 46, which is my "System.Assert(e.getMessage()...." line.  This seems pretty straightforward...I'm asking it to try to delete the record (which should throw an error due to my trigger) then catch the error and ensure it matches the error message in my trigger.

When I comment out line 46, my test case passes with 85% coverage.  Like it is, it simply fails.  The error message it gives me when it fails is: "Class.testCannotDeleteCampaignMember.runTestDelete: line 46, column 1".  Of course, it can't delete the record...that's what my trigger is designed to prevent.

Can anyone tell me why my test case is failing when I try to catch the error message in row 46?
Abhishek BansalAbhishek Bansal
Hi Patrick,

I tried the same scenario in my tes org and face the same issue. I also tried to modify the string by making some adjustment into it but ecan ane evry time it fails even though it contains the text thet we are using for comaprison. I am not sure what makes it to fail every time but I was able to run the test class sucessfully after removing the string "If you are on the Marketing Team and would like to delete this Campaign Member, go to the Lead and remove the value from the "Current Campaign" field first." If it is possible the please use the below statement in your test class:
System.Assert(e.getMessage().contains('Only the Marketing Team can delete Campaign Members.'));

My assumption is that it is failing due to the space that we are using between "Members." and "If you". Let me know if you need further inofrmation on this.

Thanks,
Abhishek Bansal.