I checked the other answers about this topic but I have no clear result. I think Id pricebookId = Test.getStandardPricebookId(); is use to get a standardPrice before insertion of PricebookEntry in a Test Context.

But in my case, I want to create a Pricebook2 and then, after insert it, create a PricebookEntry related with the Pricebook2 previous inserted. I'm trying and I have the STANDARD_PRICE_NOT_DEFINED error.

So... I need to use Test.getStandardPricebookId() despite of I'm not creating test class? I clarify that my objective is not pass a Test Class; I need a Web Service process that take the gotten JSON data, with data of Pricebook2 and PricebookEntry, and create new Salesforce objects with this data.

Here my code:

for (EP_WSAPIsForSFRecordsWrapper.PA pricebook : pAToSave_list) {
            Pricebook2 newPB2 = new Pricebook2();

            newPB2.ExternalId__c = pricebook.external_id; //Which is 001
            newPB2.IsActive = pricebook.isactive;
            newPB2.Name = pricebook.name;
        //PB2 UPSERT
       upsert pb2ToUpsert_lst;
        //PBE LOGIC
        String newRelatedPricebook2 = [SELECT Id, ExternalId__c FROM Pricebook2 WHERE ExternalId__c =:'001' LIMIT 1].ID;
        List<PricebookEntry> pbeToUpsert_lst = new List<PricebookEntry>();
        for (EP_WSAPIsForSFRecordsWrapper.PA prcbook : pAsToSave_list) {
            PricebookEntry newPBE = new PricebookEntry();
            newPBE.ExternalId__c = prcbook.external_id;
            newPBE.IsActive = prcbook.isactive;
            newPBE.UnitPrice = prcbook.unit_price;

           // This is the condition that is set to true if we are in a Test context.
            if(isTestPricebookRunning) {
                Id pricebookId = Test.getStandardPricebookId();
                newPBE.Pricebook2Id = pricebookId;
            } else {
                newPBE.Pricebook2Id = newRelatedPricebook2;
        upsert pbeToUpsert_lst;

Then, the main question: I need to use the Test.getStandardPricebookId() also out of testing? Or there are options to define the Standard Price without that? Because I tried to set the IsStandard field on the created Pricebook2 to true, but is not writeable and it is false.

1 Answer 1


Using the Standard Price Book

The standard price book is already there in the test context, you just need to activate the standard price book before you use it, you can use the below TestDataFactory method to do that.

public static PriceBook2 activateStdPriceBook() {
    PriceBook2 standardPriceBook = new Pricebook2(
        Id = Test.getStandardPricebookId(),
        IsActive = true
    upsert standardPriceBook;
    return standardPriceBook;

Once you define the factory method you can call it and insert the price book entries.

Using a Custom Price Book

Even if you are not using the Standard PriceBook you must have to define the PriceBookEntries for all of the Products. Then only you will be able to add the products in the Opportunity/Quote/Order/WorkOrder.

To use the custom pricebook you need to activate the standard pricebook also, insert price book entries for both custom and standard price book. You can do that like below.

PriceBook2 priceBook = new PriceBook2(
    Name = ProductUtil.JS_PRICE_BOOK,
    IsActive = true
insert priceBook;

// insert pricebook entries for both price books.

You must log in to answer this question.

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