1

I am trying to create a test class for my Before Insert Trigger. The trigger appears to be working well in sandbox. Looking at my debugs, it looks like I have everything there, and that the trigger code is populating the fields, but the insertion fails

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, PopulateStandardPrice: execution of BeforeInsert caused by: System.ListException: List index out of bounds: 0 Trigger.PopulateStandardPrice: line 6, column 1: []).

I'm new to apex coding, so I'm sure I've made a basic mistake.

Here is the Trigger code:

trigger PopulateStandardPriceUpdate on Product_Request__c (before insert) {
    //uses item description to look up item number in pricebook and populate standard price field from pricebook in decimal format
 
     for (Product_Request__c PR : Trigger.new){
       
         // Retrieve description and item number fields:
        
        String ItemNumber = PR.Item_Number__c;   
        String Description = PR.Description__c;
        String PricingRequestID = PR.Pricing_Request__c;
     
        System.debug('Product Request Product Code: ' + ItemNumber+ 'Product Request Description__c:  ' + Description + 'Product Request Pricing Request ID' +  PricingRequestID);

        //Checks that description field is entered to proceed:
        If(Description != NULL){
           
        //look up price book from item number/product code:
        //Note-- use of LIMIT 1 for pricebook entry-- selects first pricebook entry.
          
        List<PricebookEntry> PriceBookList= [Select UnitPrice, ProductCode
                                FROM PricebookEntry
                              WHERE ProductCode=: ItemNumber
                              LIMIT 1
                              ]; 
            //returns unit price as a decimal:    

       Decimal Price = [Select UnitPrice 
                       FROM PricebookEntry 
                       WHERE ProductCode =: ItemNumber LIMIT 1].UnitPrice;
       
       
     //insert price into record:
      PR.Standard_Price__c=Price;
                        
     //Check values: 
        System.debug('ItemNumber: ' + ItemNumber);
        System.debug('Description: ' + Description);
        System.debug('PriceBookList: ' + PriceBookList);
        System.debug('Price: ' + Price);
        System.debug('PricingRequest:' + PricingRequestID);
        System.debug('Inserted Price: ' + PR.Standard_Price__c);
        }
        
         Else{
        //Prompts for description field to be entered:
    
            PR.addError('Enter Product Description');
            System.debug('No product description was entered');        
         }           
    }
}

And here is the test class (sorry-- there was a lot to set up in terms of records):

@isTest
private class PopulateStandardPriceUpdateTest {
       //tests PopulateStandardPriceUpdate for code coverage for deployment to production 

    @testSetup static void setup()
    {
        //Create required fields ship to account
        Account acc = new Account(name='Test Hospital');
        insert acc;
        
        Ship_To__c ShipTo = new Ship_To__c(Name = 'Test Hospital',Account__c=acc.Id);
        insert ShipTo;
        
        //Create required fields: product

        Product2 product = new Product2(name= 'Test Product',productcode= '123456');
        insert product;
        
        System.debug('Check Accounts and product created: ' + 'Account: ' + acc.ID +'   Product: ' + product.ID);
    
        //Get standard Pricebook and insert standard price
        Id pricebookId = Test.getStandardPricebookId();
        
        System.debug('Check Pricebook entry Id: ' + pricebookId);
        
         // Insert a price book entry for the standard price book.
        // Standard price book entries require the standard price book ID we got earlier.
        PricebookEntry standardPrice = new PricebookEntry(Pricebook2Id = pricebookId, 
                                                          Product2Id = product.Id,
                                                          UnitPrice = 1.00, 
                                                          IsActive = true);
        insert standardPrice;
        
        //Create custom PriceBook and PriceBookEntry
        Pricebook2 PB = new Pricebook2(name= 'Test PriceBook');
        insert PB;
        PricebookEntry PBE = new PricebookEntry(Pricebook2ID= PB.Id,    //references look up to test pricebook
                                                Product2ID = product.Id,  //references look up to product ID
                                                UnitPrice = 2.00,
                                                IsActive = TRUE
                                               );
        insert PBE;
        //String ProductCode = PBE.ProductCode;
        
        List<PricebookEntry> PBEs = [Select ProductCode, UnitPrice From PricebookEntry Where ProductCode = '123456' ];
        
        System.debug('Price Book Entries Created:   ' + PBEs);
        
       //System.debug('Product Code: ' + ProductCode);
        
                //Create Pricing Request
        Pricing_Request__c PricingRequest = new Pricing_Request__c(Type__c = '$0 Request',
                                                                   Account__c=acc.Id);
        insert PricingRequest;
        String PricingRequestNumber = PricingRequest.Id;
        
        System.debug('Pricing Request ID Number: ' + PricingRequestNumber);
    }
//
//Start Test: create product request
//
   @ isTest static void insertProductRequest()
    {
        //Retrieve Account: 
        
        Account acc = [Select ID From Account Where Name = 'Test Hospital' Limit 1];
        
        Product2 product = [Select ID, Name, ProductCode From Product2 Where Name = 'Test Product' Limit 1];
        
        System.debug('Retrieve Product ID:  ' + Product);
        
        Ship_To__c ShipTo = [Select ID, Name, Account__c, Country__c From Ship_To__c Where Name = 'Test Hospital' Limit 1];

        
        System.debug('Retrieve Ship To: ' + ShipTo);

        Pricing_Request__c PricingRequest = [Select ID, Type__c, Account__c, Status__c, Name From Pricing_Request__c Limit 1];
        
        System.debug('Pricing Request Created: ' + PricingRequest);



        //Create New Product Request
        Product_Request__c PR = new Product_Request__c(Description__c= product.id,
                                                       PO_Number__c='FREE OF CHARGE', 
                                                       Ship_To_Description__c= ShipTo.Id,
                                                       Pricing_Request__c = PricingRequest.Id
                                                                   );
        System.debug('Product Request Entry before insert: ' + PR);
        
        Test.startTest();
        //Insert record for trigger: 
            insert PR;
        Test.stopTest();

        //Return inserted record and check values: 

        
        PR = [Select Item_Number__c, Standard_Price__c From Product_Request__c Where id=:PR.id];
       
        
        
        String ItemNumber = PR.Item_Number__c;
        Decimal StandardPrice = PR.Standard_Price__c;
        
        System.Debug('New Record Item Number: '+ ItemNumber);
        System.Debug('New Record Standard Price: ' + StandardPrice);
        
        
        
       System.assertEquals(1.00,StandardPrice);

        
    }
}
1
  • I'm not seeing anything that would generate that particular error (which would be something like myList[0] when myList is empty). Are you certain that this is the error you're getting? Are the first 6 lines of your PopulateStandardPriceUpdate trigger exactly the same as what you have in the org you're running this test in? It could be helpful to edit your question to mark the problematic line in your trigger and/or include the problematic line as a separate code block.
    – Derek F
    Mar 9, 2021 at 12:28

2 Answers 2

0

This code appears not to be at fault. The responsible trigger is called PopulateStandardPrice, while this trigger is called PopulateStandardPriceUpdate (although it is running on insert, which is likely to be a source of confusion).

This is a great impetus to adopt a trigger framework, have a single trigger per object, and move all of your trigger logic into a handler class. Kevin O'Hara's framework is a popular one, but what's most important is that you have a framework, not that it's this one or that one. Using a trigger handler framework makes it much easier to trace and manage the path of execution through complex automation, and can also help you write cleaner unit tests for your code.

0

Thanks all for your help--- your advice solved it. There was another trigger code written for the same object that I wasn't aware of that was causing the error. This is why the error message wasn't making sense based on the code I was running. Moving everything to a single trigger handler class as suggested.

You must log in to answer this question.

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