3

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???
        test.startTest();
        APM_Applications__c[] newRecords = database.query(getAllFieldsForSOQL());
        system.debug(getAllFieldsForSOQL());
        APM_ApplicationHandler ah = new APM_ApplicationHandler(newRecords);        
        ah.afterUpsert();
        test.stopTest();        
        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
        }
    }

1 Answer 1

5

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.

5
  • 1
    note to self. After working on a single issue for more than 4 hours post to stackexchange.
    – tjcinnamon
    May 11, 2017 at 14:16
  • Heh. Problem solved?
    – Adrian Larson
    May 11, 2017 at 14:17
  • What happened to your elide method? What's with the boring old coalesce?
    – sfdcfox
    May 11, 2017 at 15:10
  • 2
    @tjcinnamon vote early and vote often.
    – sfdcfox
    May 11, 2017 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, 2017 at 15:20

You must log in to answer this question.

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