function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Shawn Reichner 29Shawn Reichner 29 

Null Pointer on Test Class

Hello all! 

I have a trigger which operates just fine for all scenarios (Insert, Update, Delet and undelete) but when i am attempting to create a test class for the trigger to test my first scenario I am getting a null pointer exception with the folllowing error: 

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, AcctSubMrrRollup: execution of AfterInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.AcctSubMrrRollup: line 18, column 1: []

Please see my Trigger and test class below, can anyone advise what i may e doing incorrect as in theory my trigger should be doing things correctly and I am not sure why my Map is Null even after fulfillign the If statement criteria on not being null?

Please help...

Thanks for your time,

​Shawn

Trigger Code: 
trigger AcctSubMrrRollup on Zuora__SubscriptionProductCharge__c(after insert, after update, before delete, after unDelete) {
    List<Id> AccIds=new List<Id>();
    
If(Trigger.isInsert || Trigger.isUpdate || Trigger.isUnDelete) {
    for(Zuora__SubscriptionProductCharge__c mst:Trigger.New){
    if(mst.Zuora__Account__c !=null){
     AccIds.add(mst.Zuora__Account__c);
    }
    }
   

   Map<Id,Account> AccMap = new Map<Id,Account>([select id,Subscription_MRR__c from Account where id in:AccIds]);
   
   for(Zuora__SubscriptionProductCharge__c mst:Trigger.New)
   {
        if(!AccMap.IsEmpty())
        {
            AccMap.get(mst.Zuora__Account__c).Subscription_MRR__c = AccMap.get(mst.Zuora__Account__c).Subscription_MRR__c + mst.Zuora__MonthlyRecurringRevenue__c;
        }
   }

   if(!AccMap.IsEmpty())
   {
        update AccMap.values();
   }}
   
   If(Trigger.isDelete) {
    for(Zuora__SubscriptionProductCharge__c mst:Trigger.Old){
    if(mst.Zuora__Account__c !=null){
     AccIds.add(mst.Zuora__Account__c);
    }
    }
   

   Map<Id,Account> AccMap = new Map<Id,Account>([select id,Subscription_MRR__c from Account where id in:AccIds]);
   
   for(Zuora__SubscriptionProductCharge__c mst:Trigger.Old)
   {
        if(!AccMap.IsEmpty())
        {
            AccMap.get(mst.Zuora__Account__c).Subscription_MRR__c = AccMap.get(mst.Zuora__Account__c).Subscription_MRR__c - mst.Zuora__MonthlyRecurringRevenue__c;
        }
   }

   if(!AccMap.IsEmpty())
   {
        update AccMap.values();
   }}

}

Test Class Code:
@isTest
public class AcctSubMrrRollupTest {

    public static testMethod void tm1 (){
        
     Account a = new Account();
        a.Name = 'Test Account Rollup';
        
        insert a;
        
        System.debug('The Id for the newly created Account is ' + a.Id);
        
     Zuora__SubscriptionProductCharge__c z1 = new Zuora__SubscriptionProductCharge__c();
        z1.Name = 'Testing 1';
        z1.Zuora__Zuora_Id__c = '12345';
        z1.Zuora__MonthlyRecurringRevenue__c = 100;
        z1.Zuora__Account__c = a.Id;
        
        insert z1;
        
        System.debug('The ID for the newly created Sub Record is ' + z1.Id);
        
        System.assertEquals(100, a.Subscription_MRR__c);
        
    }
    
}

 
Best Answer chosen by Shawn Reichner 29
Glyn Anderson 3Glyn Anderson 3
Shawn,

I think the problem is that your test does not initialize the "Subscription_MRR__c" field of your test record.  Set this field to zero in your test code.  As it is, the trigger is trying to add the monthly recurring revenue to null - causing the NullPointerException.

And, for the benefit of your education, I must disagree with Sandeep on two points.  When a query finds no records, it will return an empty list.  So your map will always be instantiated, but it might be empty.  Second, doing DML on an empty collection does not cause an error and it also does not count against your DML limits.  So there is no reason to wrap your DML statements in code to check whether the collection is empty.  It is just inefficient.

All Answers

Shawn Reichner 29Shawn Reichner 29
I am still receiving the same null pointer error afte rmakign the changes you provided.  Thanks for your input it was very helpful for my education, however it did not resolve this issue :(
Sandeep WaliaSandeep Walia
Hi Shawn,

Had a look at your test class and noticed that you are not entering any value in the Subscription_MRR__c( on line 8 of test class) in you account, but you are querying the same field in your class. The updated assert will be the sum of  Subscription_MRR__c and Zuora__MonthlyRecurringRevenue__c fields.
 
@isTest
public class AcctSubMrrRollupTest {

    public static testMethod void tm1 (){
        
     Account a = new Account();
        a.Name = 'Test Account Rollup';
        a.Subscription_MRR__c= 100;//Enter the desired value for Subscription_MRR__c
        insert a;
        
        System.debug('The Id for the newly created Account is ' + a.Id);
        
     Zuora__SubscriptionProductCharge__c z1 = new Zuora__SubscriptionProductCharge__c();
        z1.Name = 'Testing 1';
        z1.Zuora__Zuora_Id__c = '12345';
        z1.Zuora__MonthlyRecurringRevenue__c = 100;
        z1.Zuora__Account__c = a.Id;
        
        insert z1;
        
        System.debug('The ID for the newly created Sub Record is ' + z1.Id);
        
        System.assertEquals(200, a.Subscription_MRR__c);//Updated to the sum of Subscription_MRR__c and Zuora__MonthlyRecurringRevenue__c  fields
        
    }
    
}

Hope this helps,
Sandeep
 
Glyn Anderson 3Glyn Anderson 3
Shawn,

I think the problem is that your test does not initialize the "Subscription_MRR__c" field of your test record.  Set this field to zero in your test code.  As it is, the trigger is trying to add the monthly recurring revenue to null - causing the NullPointerException.

And, for the benefit of your education, I must disagree with Sandeep on two points.  When a query finds no records, it will return an empty list.  So your map will always be instantiated, but it might be empty.  Second, doing DML on an empty collection does not cause an error and it also does not count against your DML limits.  So there is no reason to wrap your DML statements in code to check whether the collection is empty.  It is just inefficient.
This was selected as the best answer
Shawn Reichner 29Shawn Reichner 29
Glyn, thank you very much for the advice and the education.  This did the trick after initializing the MRR field and commenting out my assertion line.   Thank you again for your help! 
Sandeep WaliaSandeep Walia
Have retaracted my initial answer.

This is what I love about this forum. You come here to help others and end up learning so much yourself. Thanks for the answer Mr Anderson;) was following this habit of being over cautious since so long!

Sandeep
Glyn Anderson 3Glyn Anderson 3
Sandeep,  I see a lot of people doing the same thing.  I see it a lot here in the forum.  It's "just the way it's done".  But I'm glad to tell the world that it doesn't have to be that way.  We can all save a few keystrokes!  Thank you for being a forum contributor!