+ Start a Discussion
ronaldheftronaldheft 

Custom Setting Returning Null in Context of Trigger

I'm working with an organization that has a large amount of Apex code developed with previous contractors, and I've run into some issues with getting my new code playing nice with the existing Apex.

 

I've written a new controller which requires an Account object for testing. I'm creating the Account object as follows:

public static Account getAccount(){
    return new Account(
        Name = 'Test Acc EL CH FB',
        Squad_Class__c = 'CH - Cheer',
        Squad_Type__c = 'EL - Elementary',
        Squad_Group__c = 'FB - Football',
        BillingStreet = 'Test Bill Address',
        BillingCity = 'Test Bill City',
        BillingState = 'CA',
        BillingCountry = 'US',
        Billing_County__c = 'US',
        BillingPostalCode  = '523622',
        RecordTypeId = [select Id from RecordType where SObjectType ='Account' and Name = 'Squads/Teams' Limit 1][0].Id
    );
}

 

This is called from the test as so:

Account acc = AllStarTestUtils.getAccount();
insert acc;

 

On insert an existing Trigger written by a previous contractor is run:

trigger NewAccountTrigger on Account (before insert) {
    AccountSettings__c acctSettings = AccountSettings__c.getOrgDefaults();
    Double CustAutoNum = acctSettings.DB2_Customer_Number_Auto__c;
    ...

 

When I run my test I'm seeing the code bomb out on line 3 of the existing Trigger with the following exception:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, NewAccountTrigger: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object Trigger.NewAccountTrigger: line 3, column 1: []

 

From what I can tell, the custom settings object AccountSettings__c is null when running the test. I've verified the custom setting exists in my sandbox, and when I output the following code in the Debug Console, the logs are returning the expected value:

System.debug(AccountSettings__c.getOrgDefaults());
System.debug(AccountSettings__c.getOrgDefaults().DB2_Customer_Number_Auto__c);

 

So, it looks like everything should be working fine, but obviously this null pointer is causing problems. I read in the documentation for getOrgDefaults there was a change in the what getOrgDefaults returns when empty. In v21 or prior a NULL was returned. The existing Trigger is versioned at v20 and my new code is versioned at v24. If I bump my new code down to v20 the test passes, but it does not work in reverse; if I increase the existing trigger to v24 I still get a null pointer.

 

I should mention this Trigger is working fine outside the context of the test. Any ideas?

Henry AkpalaHenry Akpala

Did you try instantiating the object before getting any value from it? In the trigger

 AccountSettings__c acctSettings = new  AccountSettings__c(); 
jessealtmanjessealtman

I would assume that wouldn't be an issue as long as the default value is set up in the organization, unless I am mistaken. Either way, you may not want to change an existing trigger that was put in place by a different consultant.

ForceCoderForceCoder

It sounds like a bug in salesforce if you can't programmatically create a new record of Account in a newly created class because of existing code...it's like it isn't totally honoring the API version, although not consistently. ;)

 

I agree with what jersey said, as a consultant you shouldn't be making modifications to a large existing codebase like this w/o being able to fully understand everywhere it is used, regression tests, etc. 

 

could you call the method that is returning null in your test util andt if it returns null then insert a record for it?

Jaap BranderhorstJaap Branderhorst
Annotate your test class with @isTest(SeeAllData=true)

You created the custom setting outside the scope of the test class. From API version 24.0 onwards a test class cannot 'see' any data that's created before the test is run unless you annotate the test class (or testmethod) with (SeeAllData=true).
Benzeen TalhaBenzeen Talha
This is a very old discussion but I still find this useful because I have found myself in a similar situation.

I am writing a Test Class for a Global Class with a Web services method. This method  updates an Event. But there is also an Event trigger helper class that gets invoked when the update is executed. This helper class uses a custom settings value; ID of syAdmin of the org and uses this ID to assign event owner as the Sysadmin of the org. When the test class runs it fails and gives following error 

System.DmlException: Update failed. First exception on row 0 with id 00Ug0000004g3AfEAI; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, EventTrigger: execution of AfterUpdate
caused by: System.NullPointerException: Attempt to de-reference a null object

I added custom settings value in the Test class but that did not help.
  List<CaseAssignmentOwner__c> configs = new List<CaseAssignmentOwner__c>();          
        configs.add( new CaseAssignmentOwner__c(Name = 'CaseOwnerAssign_User',Value__c  = '005b0000000G0V5'));             
        insert configs;

Only work around was to set @isTest(SeeAllData=true).
Salesforce says this is not the best thing to do. But I could not find any other alternative. Or may be using ID is not such a good Idea ?