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
sssteelesssteele 

Test Class on Line Items - Field Integrity Error

I'm hoping someone can help. I'm writing a test class for a simple Line Item trigger (totally new at this). I am getting an error that the PriceBookEntryId can't be blank, but every time I try to pull in an ID, I get the error that my query returned no rows. 

 

Original trigger:

 

1
2
3
4

trigger OpportunityLineItemBeforeDelete on OpportunityLineItem (before delete) {
for (OpportunityLineItem li: Trigger.old)
    li.addError('Cannot remove a property once added. Contact support');
}

 

 

Test class that gives me the error: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: PricebookEntryId, unknown (versions 3.0 and higher must specify pricebook entry id; others must specify product id): [PricebookEntryId, unknown]

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@IsTest
public class LIDeleteClass{
    static TestMethod void InsertOppty()
    {Date myDate = date.newinstance(2014, 12, 17);
    Opportunity oppty = new Opportunity(Name='Test', StageName='IO Signed', CloseDate=myDate);
      insert oppty;
    Opportunity oppty1 = [select id, Name, Stagename, Closedate 
                          from Opportunity 
                          where Name = :'Test' LIMIT 1];

     //PricebookEntry pbe = [select Id 
       //                    from PricebookEntry
         //                  where Product2.Name = :'Amazon Ad Platform (AAP)' 
     
            //               and Pricebook2.Name = :'Standard Price Book' LIMIT 1];
    OpportunityLineItem li = new OpportunityLineItem(OpportunityId=oppty1.id, Quantity=12000,TotalPrice=12000);

      insert li;
    Test.starttest();
       try
           {
              delete li;
            
              System.assert(false);
           }
           catch (DMLException e)
           {
          
           }
    Test.stoptest();
    }}

 

When I uncomment the pbe variable, I get the error System.QueryException: List has no rows for assignment to SObject.

 

Any help would be appreciated.

Best Answer chosen by Admin (Salesforce Developers) 
manuel-jose-condemanuel-jose-conde

hi,

 

you need to make sure that PricebookEntry record is not null and then add 

PricebookEntryId = pbe.Id

to the OpportunityLineItem object.

 

also, a good pratice to follow when developing test methods is to make sure that you create all the data needed during the test - so that we don't  rely on org's data....which can be realy an issue when deploying code to production.

 

Regards

Manuel

All Answers

manuel-jose-condemanuel-jose-conde

hi,

 

you need to make sure that PricebookEntry record is not null and then add 

PricebookEntryId = pbe.Id

to the OpportunityLineItem object.

 

also, a good pratice to follow when developing test methods is to make sure that you create all the data needed during the test - so that we don't  rely on org's data....which can be realy an issue when deploying code to production.

 

Regards

Manuel

This was selected as the best answer
sssteelesssteele

Manuel,

Thanks. I thought so too, but am I able to write to the pricebook? If so, what would that look like? I was under the impression that it couldn't be written to from the class.

Shane

manuel-jose-condemanuel-jose-conde

Sure you are, see an example that I grabbed from one of my classes:

 

...

 Opportunity[] ops = new Opportunity[]{ o1,o2,o3};

        insert ops;

        Product2 p = new Product2(name='x', Description = 'desc',Product_Type__c = 'bla bla', Product_Class__c ='test');

        insert p;

        Pricebook2 stdPb = [select Id from Pricebook2 where isStandard=true limit 1];

        PricebookEntry pbe =  new PricebookEntry(pricebook2id = stdPb.id, product2id = p.id, unitprice=1.0, isActive=true);

        insert pbe; 

        OpportunityLineItem ol1 = new OpportunityLineItem (OpportunityId = o1.Id, PricebookEntryId = pbe.Id, Quantity = 1, UnitPrice = 1;

....

Note the line for the Pricebook2 

 

Regards

Manuel

sssteelesssteele

Manuel,

Thanks again. I made similar updates, but I was still getting a no rows to assign error on the Select ID from Pricebook2, even though the pricebook has products populated. I was able to assign the PricebookID manually and got 100% code coverage. I may have to make similar adjustments in prod. 

Regards!

Shane

SFAdmin5SFAdmin5

yeah this test class gets 100% but I'm not sure if it will work in prod

 

@isTest(seeAllData=true)
private class TestOLITrigger 
{

    static testMethod void TestOLITTriggerverify() 
    {

        Account acc = new Account(Name = 'Test Account');
        insert acc;

        Pricebook2  standardPb = [select id, name, isActive from Pricebook2 where IsStandard = true limit 1];

        Pricebook2 pbk1 = new Pricebook2 (Name='Test Pricebook Entry 1',Description='Test Pricebook Entry 1', isActive=true);
        insert pbk1;

        Product2 prd1 = new Product2 (Name='Test Product Entry 1',Description='Test Product Entry 1',productCode = 'ABC', isActive = true);
        insert prd1;

        PricebookEntry pbe1 = new PricebookEntry (Product2ID=prd1.id,Pricebook2ID=standardPb.id,UnitPrice=50, isActive=true);
        insert pbe1;

        Opportunity opp1 = new Opportunity (Name='Opp1',StageName='Stage 0 - Lead Handed Off',CloseDate=Date.today(),Pricebook2Id = pbe1.Pricebook2Id, AccountId = acc.id);
        insert opp1;

        OpportunityLineItem lineItem1 = new OpportunityLineItem (OpportunityID=opp1.id,PriceBookEntryID=pbe1.id, quantity=4, totalprice=200);
        insert lineItem1;

        try
        {
            Test.startTest();
            delete lineItem1;
            Test.stopTest();   
        } catch (Exception e)
        {
            System.assert(e.getDmlMessage(1).indexOf(
            'Cannot remove a property once added. Contact support') > -1); 

        }
    }
}

 

sssteelesssteele

Thanks, Ross. I'm going to try this approach, too, so I can see for myself how they both work.