+ Start a Discussion
Ben DunlapBen Dunlap 

How do I unit-test opportunity line items in Spring '12 without a Standard Price Book?

My Apex unit tests, which were all working in v23.0, are now failing in my v24.0 sandbox because there are no Pricebook2 records in the test database. I'm not sure how to fix this -- I've tried inserting my own Pricebook2 record but it doesn't make any difference, because it's not the Standard Price Book.

 

Here's my code, abbreviated:

 

Product2 newProd = new Product2(Name = 'test product', family = 'test family');
insert newProd;

PriceBookEntry pbEntry = new PriceBookEntry(
    UnitPrice = 300,
    PriceBook2Id = [select id from PriceBook2 where isStandard = true].Id,
    Product2Id = newProd.Id
);

 The query on line 6 fails with "List has no rows". But if I try this instead:

 

Product2 newProd = new Product2(Name = 'test product', family = 'test family');
insert newProd;

PriceBook2 pb = new PriceBook2(Name = 'test price book');
insert pb;

PriceBookEntry pbEntry = new PriceBookEntry(
    UnitPrice = 300,
    PriceBook2Id = pb.Id,
    Product2Id = newProd.Id
);

insert pbEntry;

 Then the last line fails with a STANDARD_PRICE_NOT_DEFINED exception.

 

Not sure how to get around this -- my understanding is that this code has stopped working in v24.0 because unit tests no longer have access to real data. How does one test opportunity line items, then?

Best Answer chosen by Admin (Salesforce Developers) 
Ben DunlapBen Dunlap

Got what seems to be a semi-official reply on Stack Overflow. It boiled down to "yes, we realize that stuff like this is going to happen -- the unit-test changes are a work in progress and you can expect the system to improve in a future release, meanwhile there's a workaround". That works for me!

All Answers

Ben DunlapBen Dunlap

Just for fun I tried sidestepping the problem by attempting to insert an OpportunityLineItem record without a PriceBookEntryId field, but as expected I got FIELD_INTEGRITY_EXCEPTION: PricebookEntryId, unknown.

NuDevNuDev

Ben, try saving the test class using the (SeeAllData=true) annotation (pg. 167 under the Spring '12 release notes) or switch the API version to 23.

Ben DunlapBen Dunlap

Thanks so much! I think the problem still indicates a bug in v24.0 (because the newly-released 'all data is clean' aspect of unit-tests actually breaks certain built-in objects) but at least I can keep working for now. Thanks again.

Ben DunlapBen Dunlap

Got what seems to be a semi-official reply on Stack Overflow. It boiled down to "yes, we realize that stuff like this is going to happen -- the unit-test changes are a work in progress and you can expect the system to improve in a future release, meanwhile there's a workaround". That works for me!

This was selected as the best answer
craigmhcraigmh

...........wow

craigmhcraigmh

Also, to add, my workaround has been to change the API version to 23 (Winter '12). I'll start developing against 24 (Spring '12) when it rolls to production instances, and hopefully, these issues will be fixed.

DimaDima

They had 3 releases since Spring 12 and this issue is still there.

If you need a pricebook you have to use seeAllData=true

David Roberts 4David Roberts 4
See https://stackoverflow.com/questions/9164986/how-do-i-avoid-standard-price-not-defined-when-unit-testing-an-opportunitylineit
for ReidCarlberg's solution from 2013.
Test.getStandardPriceBookId() gives the same Id as the select but the select route allows you to force the standard pricebook to be active.