I have created a trigger on the Project custom object, to create a record in the Project Note custom object when the description field is modified.
Running the unit test however, I receive the following error: System.NullPointerException: Attempt to de-reference a null object
Any guidance would be greatly appreciated. My trigger is as follows:
trigger ProjectNoteCreate on BPS_Projects__c (after insert, after update) {
List <Project_Note__c> notesToInsert = new List <Project_Note__c>();
for (BPS_Projects__c newProject : trigger.new)
{
BPS_Projects__c oldProject = Trigger.oldMap.get(newProject.Id);
if (oldProject.Description__c != newProject.Description__c)
{
Project_Note__c note = new Project_Note__c();
note.Project__c = newProject.Id;
note.DateStamp__c = datetime.now();
if (newProject.Description__c == null)
{
note.Note__c = '---Description was cleared---';
}
else
{
note.Note__c = newProject.Description__c;
}
notesToInsert.add(note);
}
if (notesToInsert.size()> 0)
{
insert notesToInsert;
}
}
}
The test class snippet for the above trigger is as follows (sorry for the lengthy code, there are a number of required lookup fields as well as validation rules affecting this object):
static testMethod void ProjectNoteCreate(){
test.startTest();
// Set RecordType ID values
RecordType acctrt = [select Id from RecordType where sObjectType = 'Account' and Name = 'Account (Managed)' LIMIT 1];
System.debug('The Account Record Type ID is ' + acctrt);
RecordType contrt = [select Id from RecordType where sObjectType = 'Contact' and Name = 'Partner Contact' LIMIT 1];
System.debug('The Contact Record Type ID is ' + contrt);
RecordType opprt = [select Id from RecordType where sObjectType = 'Opportunity' and Name = 'Commercial Card' LIMIT 1];
System.debug('The Opportunity Record Type ID is ' + opprt);
RecordType projrt = [select Id from RecordType where sObjectType = 'BPS_Projects__c' and Name = 'Implementation Initiative' LIMIT 1];
System.debug('The Project Record Type ID is ' + projrt);
// Create Test Account record
Account testaccount = new Account(RecordTypeID = acctrt.Id, Name = 'Test Account', Rating = 'Silver', Ownership = 'Private', Type = 'Customer', CurrencyIsoCode = 'CAD', Industry = 'Communications');
insert testaccount;
System.debug('testaccount created');
System.debug(testaccount.Id);
// Create Test Contact record
Contact testcontact = new Contact(RecordTypeID = contrt.Id, Account = testaccount, FirstName = 'John', LastName = 'Adams', Title = 'Test Subject', Management_Level__c = 'Operations', Contact_Status__c = 'Active', Phone = '555-555-5555', Lang_Pref__c = 'English', Communications__c = 'None');
insert testcontact;
System.debug('testcontact created');
System.debug(testcontact.Id);
// Create Test Opportunity record
Opportunity testopportunity = new Opportunity(RecordTypeID = opprt.Id, Name = 'Test Opp for Unit Testing', CurrencyIsoCode = 'CAD', Type = 'New Business', SPA_B2B_Involvement__c = 'Neither', StageName = 'Stage 2.0 - Suspect', CloseDate = Date.today(), Account = testaccount, Geographic_Coverage__c = 'Canada', Program_Type__c = 'Procurement Cards', LeadSource = 'Cold Call');
insert testopportunity;
System.debug('testopportunity created');
System.debug(testopportunity.Id);
// create Test Project record
BPS_Projects__c testproject = new BPS_Projects__c (RecordTypeID = projrt.Id, Name = 'Test Proj for Unit Testing', Project_Start_Date__c = date.ValueOf('2999-01-01'), Target_Date_Ops__c = date.ValueOf('2999-12-30'), Project_Stage__c = 'Planning', Complexity_Rating__c = 'Low', Account__c = testaccount.Id, Account_Status__c = 'New', Sales_Manager__c = testcontact.Id, CardType__c = 'Private', Actual_Card_Volume__c = 4, Region__c = 'CDN');
insert testproject;
System.debug('testproject created');
System.debug(testproject.Id);
// add description
testproject.Description__c = 'This is test note 1';
update testproject;
System.debug('description added to testproject');
testproject.Description__c = 'This is test note 2';
update testproject;
System.debug('description updated on testproject');
// clear description
testproject.Description__c = null;
update testproject;
System.debug('description has been cleared');
test.stopTest();
}
Error snippet from Debug Log:
15:03:34.185 (8185160045)|CODE_UNIT_FINISHED|ProjectNoteCreate on BPS_Projects trigger event AfterInsert for [a0NR0000003kAMY] 15:03:34.188 (8188865271)|DML_END|[394] 15:03:34.188 (8188947118)|EXCEPTION_THROWN|[394]|System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ProjectNoteCreate: execution of AfterInsert
caused by: System.NullPointerException: Attempt to de-reference a null object
UPDATE: Both Mr.DOS and Jenny B's answers (as well as comments from other users) have helped me get to a working trigger including 100% test coverage. Here is what I have now, pending some additional testing time in the sandbox:
Trigger:
trigger ProjectNoteCreate on BPS_Projects__c (after insert, before update) {
List <Project_Note__c> notesToInsert = new List <Project_Note__c>();
for (BPS_Projects__c newProject : trigger.new)
{
if (trigger.isInsert && newProject.Description__c != null)
{
Project_Note__c note = new Project_Note__c();
note.Project__c = newProject.Id;
note.DateStamp__c = datetime.now();
note.Note__c = newProject.Description__c;
notesToInsert.add(note);
}
if (trigger.isUpdate)
{
BPS_Projects__c oldProject = Trigger.oldMap.get(newProject.Id);
if (oldProject.Description__c != newProject.Description__c)
{
Project_Note__c note = new Project_Note__c();
note.Project__c = newProject.Id;
note.DateStamp__c = datetime.now();
if (newProject.Description__c == null)
{
note.Note__c = '---Description was cleared---';
}
else
{
note.Note__c = newProject.Description__c;
}
notesToInsert.add(note);
}
}
}
if (notesToInsert.size()> 0)
{
insert notesToInsert;
}
}
Test Class Snippet:
static testMethod void ProjectNoteCreate(){
test.startTest();
// Set RecordType ID values
RecordType acctrt = [select Id from RecordType where sObjectType = 'Account' and Name = 'Account (Managed)' LIMIT 1];
System.debug('The Account Record Type ID is ' + acctrt);
RecordType contrt = [select Id from RecordType where sObjectType = 'Contact' and Name = 'Partner Contact' LIMIT 1];
System.debug('The Contact Record Type ID is ' + contrt);
RecordType opprt = [select Id from RecordType where sObjectType = 'Opportunity' and Name = 'Commercial Card' LIMIT 1];
System.debug('The Opportunity Record Type ID is ' + opprt);
RecordType projrt = [select Id from RecordType where sObjectType = 'BPS_Projects__c' and Name = 'Implementation Initiative' LIMIT 1];
System.debug('The Project Record Type ID is ' + projrt);
// Create Test Account record
Account testaccount = new Account(RecordTypeID = acctrt.Id, Name = 'Test Account', Rating = 'Silver', Ownership = 'Private', Type = 'Customer', CurrencyIsoCode = 'CAD', Industry = 'Communications');
insert testaccount;
System.debug('testaccount created');
System.debug(testaccount.Id);
// Create Test Contact record
Contact testcontact = new Contact(RecordTypeID = contrt.Id, Account = testaccount, FirstName = 'John', LastName = 'Adams', Title = 'Test Subject', Management_Level__c = 'Operations', Contact_Status__c = 'Active', Phone = '555-555-5555', Lang_Pref__c = 'English', Communications__c = 'None');
insert testcontact;
System.debug('testcontact created');
System.debug(testcontact.Id);
// Create Test Opportunity record
Opportunity testopportunity = new Opportunity(RecordTypeID = opprt.Id, Name = 'Test Opp for Unit Testing', CurrencyIsoCode = 'CAD', Type = 'New Business', SPA_B2B_Involvement__c = 'Neither', StageName = 'Stage 2.0 - Suspect', CloseDate = Date.today(), Account = testaccount, Geographic_Coverage__c = 'Canada', Program_Type__c = 'Procurement Cards', LeadSource = 'Cold Call');
insert testopportunity;
System.debug('testopportunity created');
System.debug(testopportunity.Id);
// create Test Project record
BPS_Projects__c testproject = new BPS_Projects__c (RecordTypeID = projrt.Id, Name = 'Test Proj for Unit Testing', Project_Start_Date__c = date.ValueOf('2999-01-01'), Target_Date_Ops__c = date.ValueOf('2999-12-30'), Project_Stage__c = 'Planning', Complexity_Rating__c = 'Low', Account__c = testaccount.Id, Account_Status__c = 'New', Sales_Manager__c = testcontact.Id, CardType__c = 'Personal', Actual_Card_Volume__c = 4, Region__c = 'CDN');
insert testproject;
System.debug('testproject created');
System.debug(testproject.Id);
// add description
testproject.Description__c = 'This is test note 1';
update testproject;
System.debug('description added to testproject');
// update description
testproject.Description__c = 'This is test note 2';
update testproject;
System.debug('description updated on testproject');
// clear description
testproject.Description__c = null;
update testproject;
System.debug('description has been cleared');
// create Test Project record with description
BPS_Projects__c testproject2 = new BPS_Projects__c (RecordTypeID = projrt.Id, Name = 'Test Proj for Unit Testing', Project_Start_Date__c = date.ValueOf('2999-01-01'), Target_Date_Ops__c = date.ValueOf('2999-12-30'), Project_Stage__c = 'Planning', Complexity_Rating__c = 'Low', Account__c = testaccount.Id, Account_Status__c = 'New', Sales_Manager__c = testcontact.Id, CardType__c = 'Personal', Actual_Card_Volume__c = 4, Region__c = 'CDN', Description__c = 'Test note A');
insert testproject2;
System.debug('testproject created with description');
System.debug(testproject2.Id);
test.stopTest();
}
Thank you all once again for your help pointing me in the right direction. Since Mr.DOS' answer has received the most upvotes, I will mark his as the best answer.
Aaron
NPE
but yourinsert
should be outside of thefor loop
.