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
RedPointRedPoint 

Error testing Apex trigger

I have written a simple trigger to update the ListPrice of an OpportunityLine item.  The trigger works perfectly in the sandbox and it's very simple.  I cannot deploy it because I get the following error when trying to test it: 

CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, OppLineTrigger: execution of BeforeInsert
caused by: System.NullPointerException: Attempt to de-reference a null object

Here's the trigger:
Code:
trigger OppLineTrigger on OpportunityLineItem (before insert, before update) {
  
 OpportunityLineItem[] oli = Trigger.new;
        for (OpportunityLineItem o:oli){
       Double val = [select Discount__c from Opportunity Where Id = :o.OpportunityId][0].Discount__c;
       o.Description = String.valueOf(val) + '% Discount';
       o.UnitPrice = o.ListPrice - (o.ListPrice*(val/100));
 }   
}

Here's the test class:
Code:
public class testOppLineTrigger {

 static testMethod void testOppLineTrigger() { 
     
    Product2 p = new product2(name='x', Product_Group__c = 'BNN'); 
    insert p;  
    
    Pricebook2 stdPb = [select Id from Pricebook2 where isStandard=true limit 1]; 
    
    insert new PricebookEntry(pricebook2id = stdPb.id, product2id = p.id, 
                              unitprice=10.0, isActive=true); 
     
    Pricebook2 pb = new pricebook2(name='test'); 
    insert pb; 
    PricebookEntry pbe = new PricebookEntry(pricebook2id=pb.id, product2id=p.id, 
                                            unitprice=10, isActive=true); 
    insert pbe; 
    
    Account a = new Account(name='test acct');
    insert a;    
     
    Opportunity test_o = new Opportunity(name='test', AccountId=a.id, pricebook2id=pb.id, 
                                    stageName='Open', Discount__c = 10, 
                                    CloseDate=Date.newInstance(2006,10,10)); 
    insert test_o; 
    OpportunityLineItem test_oli = new OpportunityLineItem(opportunityid=test_o.id, 
                                      pricebookentryid=pbe.id, quantity=2, TotalPrice=20); 
    insert test_oli; 
   
       Double UP = [SELECT UnitPrice FROM OpportunityLineItem WHERE Id =:test_oli.id][0].UnitPrice;

       System.assertEquals(9, UP);               
    
    }

}

 

 

RickyGRickyG
RedPoint -

I am not all that familiar with standard objects, but are you sure that the Pricebook2 object will always contain a record where isStandard=true?  You don't add a record into this object, and other object inserts are dependent on that for their successful operation. 
RedPointRedPoint
Yes the Pricebook2 object has a record where isStandard = true.  The error is happening on this line in the trigger: 
o.UnitPrice = o.ListPrice - (o.ListPrice*(val/100));
RickyGRickyG
RedPoint -

Thanks, that helps.

But what about this line -

       Double val = [select Discount__c from Opportunity Where Id = :o.OpportunityId][0].Discount__c;

It looks like you are selecting where the Id = a discount__c value, which would probably not return a value.  Did I read that right?  If so, val would probably not have a value.
RedPointRedPoint
Discount__c is a custom field in the opportunity object with a default value of zero.  In my test class I am setting it to 10...  The select statement works fine in the application...
RedPointRedPoint
I spoke with SFDC tech support and got some help with this.  The o.ListPrice value is not available in the Trigger.new set so a simple query of the PriceBookEntry to get the list price did the trick.  New and modified code is below:

Code:
Double vList = [Select UnitPrice From PricebookEntry Where Id = :o.PricebookEntryId][0].UnitPrice;
       
o.UnitPrice = vList - (vList*(vDiscount/100));