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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.