1

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

8
  • 2
    Please post your test class
    – sfdc
    May 29, 2015 at 20:16
  • you are inserting Project Notes list inside for loop.Can you insert it outside for loop.
    – sfdc
    May 29, 2015 at 20:17
  • 1
    Does it say which line the error is happening on? Seeing the test class code would also be helpful in determining what's wrong.
    – dBeltowski
    May 29, 2015 at 20:19
  • It's not the cause of your NPE but your insert should be outside of the for loop.
    – BarCotter
    May 29, 2015 at 20:23
  • I have added the test class as well as more details from the debug log to the posting. Any assistance is greatly appreciated.
    – Aaron
    May 29, 2015 at 21:17

2 Answers 2

6

In this condition:

if (oldProject.Description__c != newProject.Description__c)

you retrieve (“dereference”) the Description__c field of the object stored in the variable oldProject. But when you're inserting a new BPS_Project__c record, Trigger.oldMap.get(newProject.Id) will return null, so in turn, oldProject will be null.

You should null-protect your condition:

if (oldProject == null || oldProject.Description__c != newProject.Description__c)
1
  • Unfortunately, just making your suggested change did not resolve the issue. I do see it's a valid point however.
    – Aaron
    May 29, 2015 at 21:14
2

It looks like your issue is trying to access a value from a null map here: BPS_Projects__c oldProject = Trigger.oldMap.get(newProject.Id);

Since an after insert triggers oldMap is null, attempting to access the Map itself will throw the NullPointerException. Take a look at this question here with a great answer demonstrating when the oldMap is null.

You can test this in the developer console using Execute anonymous:
test code

result

You must log in to answer this question.

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