You need to sign in to do that
Don't have an account?
Dave Blumenfeld
Null Pointer Exception on Campaign Member Attribution Trigger
Hi All. I am trying to write an apex trigger that writes a few fields that serve as "last touch attribution" on a lead or contact onto a campaign member so that on any given campaign we can track things like what the source channel that particular campaign response is from. I wrote a trigger that seems to be working great for both individual and bulk updates, but am having trouble with the Test Class. (a bit of background..I am actually a digital marketer who got lassooed into being the Salesforce guy, and have little to no coding experience and am a newbie so if this looks stupid try and use small words to help me understand haha. )
I am running into an issue with the error below:
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AppendLastTouchCampaignMembers: execution of BeforeInsert
caused by: System.NullPointerException: Attempt to de-reference a null object
Trigger.AppendLastTouchCampaignMembers: line 26, column 1: []
First it was appearing in line twenty five (the "if" statement which said if( cm.contactId == null). When I changed it to string.isBlank(cm.ContactId) it moved down to line 26.
Trigger:
Test Class
I am running into an issue with the error below:
System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AppendLastTouchCampaignMembers: execution of BeforeInsert
caused by: System.NullPointerException: Attempt to de-reference a null object
Trigger.AppendLastTouchCampaignMembers: line 26, column 1: []
First it was appearing in line twenty five (the "if" statement which said if( cm.contactId == null). When I changed it to string.isBlank(cm.ContactId) it moved down to line 26.
Trigger:
trigger AppendLastTouchCampaignMembers on CampaignMember (before insert) { Map<ID, Lead> myLead = new Map<ID, Lead>(); Map<ID, Contact> myContact = new Map<ID, Contact>(); Set<Id> leadIds = new Set<Id>(); Set<Id> contactIds = new Set<Id>(); for (CampaignMember cm : Trigger.new) { if (cm.ContactId == null){ leadIds.add(cm.LeadId); } else{ contactIds.add(cm.ContactId); } } myLead = new Map<ID, Lead>([SELECT id, utm_source__c, utm_medium__c, utm_term__c FROM Lead WHERE ID IN :leadIds]); myContact = new Map<Id, Contact>([SELECT id, utm_source__c, utm_medium__c, utm_term__c FROM Contact WHERE ID IN :contactIds]); for (CampaignMember cm : Trigger.new){ if (String.isBlank(cm.ContactId)) { Lead myCM = myLead.get(cm.LeadId); cm.Last_Touch_Source__c = myCM.utm_source__c; cm.Last_Touch_Medium__c = myCM.utm_medium__c; cm.Last_Touch_Term__c = myCM.utm_term__c; } else{ Contact myCM = myContact.get(cm.ContactId); cm.Last_Touch_Source__c = myCM.utm_source__c; cm.Last_Touch_Medium__c = myCM.utm_medium__c; cm.Last_Touch_Term__c = myCM.utm_term__c; } } }
Test Class
@isTest public class TestCampaignAttributionTrigger { static testMethod void TestCampaignMember (){ Test.startTest(); //Creates Contact to be linked to Campaign Member Contact testContact = new Contact(FirstName = 'TestContactF', LastName = 'TestContactL', Email = 'none@navinet.net', utm_source__c = 'discover', utm_medium__c = 'bought database', utm_term__c = 'test'); Lead testLead = new Lead(FirstName = 'Dave', LastName = 'Blum', Company = 'DaveCorp', Email = 'dblum@xl.com', utm_source__c = 'discover', utm_medium__c = 'bought database', utm_term__c = 'test'); insert testContact; insert testLead; //Creates a new campaign Campaign c = new Campaign(Name='Test', Status='In Progress'); insert c; //Assign Lead & Contact to campaign CampaignMember newMember2 = new CampaignMember(Campaign = [SELECT Id FROM Campaign WHERE Status = 'In Progress' LIMIT 5], Lead = testLead); insert newMember2; CampaignMember newMember = new CampaignMember(Campaign = [SELECT Id FROM Campaign WHERE Name = 'Test' LIMIT 5], Contact = testContact); insert newMember; Test.stopTest(); } }
Dave Blumenfeld
Update...I seem to have solved it with this TestClass for 100% code coverage....dunno if anything is still fishy though, so please feel free to peruse and comment!