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);
        }
    }
}
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.

  • nice -- you are three minutes smarter :-) – cropredy Dec 16 '15 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. – Daniel Ballinger Dec 16 '15 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;
  • Ah! Thank-you! If you can't tell I'm new to Apex. :) – okay56k Dec 16 '15 at 1:28
  • you should have given Daniel's answer as the solution - he pegged it first – cropredy Dec 16 '15 at 2:41
  • Fair enough, will do. – okay56k Dec 16 '15 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?

  • I'll expand the code. :) – okay56k Dec 15 '15 at 23:55

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.