+ Start a Discussion
Michael MongeauMichael Mongeau 

PricebookEntry.Product2ID is null in a test class.

I have a test function with seeAllData=true declared.  It creates an opportunity, queries the PricebookEntry object for a specific record, and then creates an opportunity line referencing that pricebook entry.
The first two System.debug statements return a record ID for the PricebookEntry and related Product2 entry.   When the PricebookEntry ID is assigned to an opportunity line item and then referenced as oli.PricebookEntry.Product2Id the value is 'null'.  What is going on here, where the SOQL query result shows a value but assigning it to a line causes it to be null?
 
@isTest(seeAllData=true)
    public static void integrationTest(){
        Account testAccount = TestUtil.createAccount();
        Opportunity o = TestUtil.createOpportunity(testAccount.Id);
        String currencyCode = [select CurrencyIsoCode from Opportunity where Id = :o.Id].CurrencyIsoCode;
        PricebookEntry pe1 = [select Id,Product2Id 
                              from PricebookEntry 
                              where IsActive = true 
                              and Pricebook2.IsStandard = true 
                              and CurrencyIsoCode = :currencyCode 
                              limit 1];
        System.debug('>>> pe1.Id = ' + pe1.Id);
        System.debug('>>> pe1.Product2Id = ' + pe1.Product2Id);
        OpportunityLineItem oli1 = new OpportunityLineItem(
            OpportunityId = o.Id,
            Quantity = 1,
            UnitPrice = 1,
            Configurator_Timestamp__c = Datetime.now()
        );
        oli1.PricebookEntryId = pe1.Id;
        System.debug('>>> oli1.PricebookEntryId = ' + oli1.PricebookEntryId);
        System.debug('>>> oli1.PricebookEntry.Product2Id = ' + oli1.PricebookEntry.Product2Id);
Debug output.

debug output
Naga  AlapatiNaga Alapati
Hi Michael,

You are assigning PricebookEntryId value only to opportunityLineItem. If you need product2Id too, then try to add the line 20 as shown below
@isTest(seeAllData=true)
    public static void integrationTest(){
        Account testAccount = TestUtil.createAccount();
        Opportunity o = TestUtil.createOpportunity(testAccount.Id);
        String currencyCode = [select CurrencyIsoCode from Opportunity where Id = :o.Id].CurrencyIsoCode;
        PricebookEntry pe1 = [select Id,Product2Id 
                              from PricebookEntry 
                              where IsActive = true 
                              and Pricebook2.IsStandard = true 
                              and CurrencyIsoCode = :currencyCode 
                              limit 1];
        System.debug('>>> pe1.Id = ' + pe1.Id);
        System.debug('>>> pe1.Product2Id = ' + pe1.Product2Id);
        OpportunityLineItem oli1 = new OpportunityLineItem(
            OpportunityId = o.Id,
            Quantity = 1,
            UnitPrice = 1,
            Configurator_Timestamp__c = Datetime.now()
        );
        <b>oli1.PricebookEntry = pe1;</b>
        oli1.PricebookEntryId = pe1.Id;
        System.debug('>>> oli1.PricebookEntryId = ' + oli1.PricebookEntryId);
        System.debug('>>> oli1.PricebookEntry.Product2Id = ' + oli1.PricebookEntry.Product2Id);
Regards,
Naga
Michael MongeauMichael Mongeau
The assignment oli1.PricebookEntry = pe1;  results in the error 'Illegal assignment from PricebookEntry to Id' and the template will not save.
Naga  AlapatiNaga Alapati
Okay. I tried that and it didn't throw any error to me. Is there any reason to use product2id from PriceBookEntry instead of using opportunityLineItem Product2Id field. Something like this:

oli.PricebookEntryId = pe1.Id;
oli.Product2Id = pe1.Product2Id;
System.debug('>>> oli1.PricebookEntryId = ' + oli1.PricebookEntryId);
System.debug(>>> oli1.PricebookEntry.Product2Id ' + oli1.Product2Id);


User-added image
Michael MongeauMichael Mongeau
Apologies. I had neglected to change the left side of the assignment from PricebookEntryId to just PricebookEntry.  Once I did I am getting the related Product2 data.  Thanks!