3

Why am I returning null in this test when everything has a value? I can't put it more simply, but it's driving me crazy.

Log

Here's the (simplified) Apex code:

public class CalculatorTest {
    static testMethod void validateCalculator() {
        Decimal annualSavings, cumulativeSavings = 0;

        annualSavings = 1014.3...;

        for (Integer i = 0; i < 20; i++) {
            annualSavings *= 1.1;

            System.debug('annualSavings: ' + annualSavings);
            System.debug('cumulativeSavings: ' + cumulativeSavings);

            cumulativeSavings += annualSavings; // this returns an error, but you can see in the log the value is null

        }
    }
}

What am I doing wrong? It makes perfect sense to me.

EDIT

I know it's in the wrong order above. If I switch the two bottom lines I get no cumulativeSavings output and this error:

Null object

EXPANDED CODE

@isTest
public class CalculatorTest {
    static testMethod void validateCalculator() {
        Decimal annualCostWonew, annualSavings, cumulativeSavings, newCost,
                oldCostAfternew, yearOneSavings, yearOneSavingsMo = 0;

        Decimal annualCost          = 4000;
        Decimal annualUsage         = 15000;
        Decimal newRate             = 0.210;
        Decimal systemDeclineRate   = 0.7 / 100;
        Decimal systemProduction    = 16000;
        Decimal oldInflation        = 8.0120 / 100;
        Decimal oldRate             = 0;

        oldRate = (oldRate == 0) ? ((annualCost / annualUsage) + annualCost / annualUsage * oldInflation) : oldRate;

        Lead l = new Lead(LastName = 'Smith', Company = 'Smith Co',
                          Annual_Cost__c = annualCost,
                          Annual_Usage__c = annualUsage,
                          New_Rate__c = newRate,
                          System_Decline_Rate__c = systemDeclineRate,
                          Old_Inflation__c = oldInflation,
                          System_Production__c = systemProduction);
        insert l;

        for (Integer i = 0; i < 20; i++) {
            if (i > 0) {
                systemProduction    *= (1 - systemDeclineRate);
                oldRate             *= (1 + oldInflation);
            }

            oldUseAfternew      = annualUsage - systemProduction;
            annualCostWonew     = annualUsage * oldRate;
            oldCostAfternew     = oldUseAfternew * oldRate;
            newCost             = systemProduction * newRate;
            annualSavings       = annualCostWonew - (oldCostAfternew + newCost);

            System.debug('oldUseAfternew: ' + oldUseAfternew);
            System.debug('annualCostWonew: ' + annualCostWonew);
            System.debug('oldCostAfternew: ' + oldCostAfternew);
            System.debug('newCost: ' + newCost);
            System.debug('annualSavings: ' + annualSavings);

            cumulativeSavings += annualSavings;
            System.debug('cumulativeSavings: ' + cumulativeSavings);
        }
    }
}

3 Answers 3

4

The problem appears to be in the declaration and initialization of the variables.

Try the following:

Decimal cumulativeSavings, oldUseAfternew = 0;

System.debug('oldUseAfternew: ' + oldUseAfternew);
System.assertEquals(0, oldUseAfternew);

System.debug('cumulativeSavings: ' + cumulativeSavings);
System.assertEquals(0, cumulativeSavings, 'cumulativeSavings should be initialized');

System.AssertException: Assertion Failed: cumulativeSavings should be initialized: Expected: 0, Actual: null

Only the last variable gets assigned the initial value of 0. Any other proceeding variables on the same line will be null.

2
  • nice -- you are three minutes smarter :-)
    – cropredy
    Commented Dec 16, 2015 at 1:17
  • "Missed it by that much". +1 for you for the Apex doc reference with the correct way to handle multiple variable initialization. Commented Dec 16, 2015 at 1:20
4

The problem you have is in the declaration statement and initialization of variables. Let's look at an example:

Decimal foo, bar = 0;
system.debug(LoggingLevel.INFO,'foo='+foo+' bar='+bar);

Results in:

17:06:29:108 USER_DEBUG [2]|INFO|foo=null bar=0

and

Decimal foo = 0, bar;
system.debug(LoggingLevel.INFO,'foo='+foo+' bar='+bar);

Results in:

17:14:16:025 USER_DEBUG [2]|INFO|foo=0 bar=null

In your code, the assignment of 0 applies only to the last variable in the list.

In the example from the Apex Developer doc, this is how Apex supports multiple initialized declarations on the same statement:

Integer i = 0, j, k = 1;
3
  • Ah! Thank-you! If you can't tell I'm new to Apex. :)
    – t56k
    Commented Dec 16, 2015 at 1:28
  • you should have given Daniel's answer as the solution - he pegged it first
    – cropredy
    Commented Dec 16, 2015 at 2:41
  • Fair enough, will do.
    – t56k
    Commented Dec 16, 2015 at 2:47
3

It works for me in an Execute Anonymous window.

This is my slightly modified code to get it working:

public void validateCalculator() {
    Decimal annualSavings, cumulativeSavings = 0;

    annualSavings = 1014.3;

    for (Integer i = 0; i < 20; i++) {
        annualSavings *= 1.1;

        System.debug('annualSavings: ' + annualSavings);
        System.debug('cumulativeSavings: ' + cumulativeSavings);

        cumulativeSavings += annualSavings; // this returns an error, but you can see in the log the value is null

    }
}

validateCalculator();

Perhaps as part of you simplification you've made an error?

1
  • I'll expand the code. :)
    – t56k
    Commented Dec 15, 2015 at 23:55

You must log in to answer this question.

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