I'm attempting to write a test method for my constructor and when I get to a method in my non-test class where I'm assigning a value to the object passed I get a "attempt to de-reference null object error".

I know there are many topics on here but most that I've searched are "code specific". I've looked.

Here is my test method class for the constructor:

static testmethod void testConstructor(){
        system.debug('****************************BEGIN TEST CONSTRUCTOR******************');
        populateAll();  //writes test objects to the database???
        APM_Applications__c[] newRecords = database.query(getAllFieldsForSOQL());
        APM_ApplicationHandler ah = new APM_ApplicationHandler(newRecords);        
        system.debug('****************************END TEST CONSTRUCTOR******************');

Here is my test class to populate data:

   static testMethod map<string, id> populateAll(){

            insert populateReferenceTable();
            insert populateBlankApps();
            map<string, id> apps = new map<string, id>();
            list<APM_Applications__c> appIds = [select id from APM_Applications__c order by CreatedDate desc limit 2];
            insert populateWarehouse(appIds[0].id, appIds[1].id);
            apps.put('app1', appIds[0].id );
            apps.put('app2', appIds[1].id );
            list<Application_Component__c> components = [select id from Application_Component__c order by CreatedDate desc limit 6 ];       
            return apps;

static testmethod list<APM_Applications__c> populateBlankApps(){
        list<APM_Applications__c> apps = new list<APM_Applications__c>();
        apps.add(new APM_Applications__c(name='app1'));
        apps[0].Annual_Cost_of_Ownership__c = 0;
        apps.add(new APM_Applications__c(name='app2'));
        apps[1].Annual_Cost_of_Ownership__c = 0;

        return apps;

Here's where I'm getting the error:

public static void updateTotalCost(APM_Applications__c app){
        system.debug(app.id);  //APP ID EXISTS MEANING APP EXISTS
        if (app.id != null){ //defensive coding just in case
            app.Annual_Cost_of_Ownership__c = app.Labor_Cost__c + app.Licensing_Cost__c + app.Infrastructure_Cost__c;        //error happens here

You cannot sum null. In other words, this code will always fail:

Integer a = null;
Integer b = 1234;
Integer c = a + b;

If you want to code defensively, don't protect against app.Id being null, protect against the sum components being null. A common method is to coalesce null to zero:

public Decimal coalesce(Decimal input) { return input == null ? 0 : input; }

Integer a = null;
Integer b = 1234;
Integer c = coalesce(a) + coalesce(b);
system.assertEquals(b, c, 'Nulls should coalesce to the additive identity');

If you can't change the updateTotalCost method for some reason, your only option is to set up your data with all three fields populated.

  • 1
    note to self. After working on a single issue for more than 4 hours post to stackexchange.
    – tjcinnamon
    May 11 '17 at 14:16
  • Heh. Problem solved?
    – Adrian Larson
    May 11 '17 at 14:17
  • What happened to your elide method? What's with the boring old coalesce?
    – sfdcfox
    May 11 '17 at 15:10
  • 2
    @tjcinnamon vote early and vote often.
    – sfdcfox
    May 11 '17 at 15:11
  • @sfdcfox spent a lot of time digging through the data explorer yesterday and coalesce was used in a few of the queries. I guess it's probably more widely understood, seeing as how it's also used in both ideas.
    – Adrian Larson
    May 11 '17 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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