I am trying to test a controller that I have written which queries SBQQ__QuoteLine__c objects. I am running into an error which is preventing me from inserting the object during the @TestSetup method.
I believe it is because I am missing a field on the SBQQ__QuoteLine__c object, but I cannot figure it out because I am unable to see the code in the managed package. Has anyone run into this before?
Error
System.DmlException: Insert failed. First exception on row 0; first
error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, SBQQ.QuoteLineAfter:
execution of AfterInsertcaused by: System.NullPointerException: Attempt to de-reference a null
objectClass.SBQQ.QuoteLineVO.getCostScheduleId: line 1729, column 1
Class.SBQQ.QuoteVO.getDiscountScheduleIds: line 251, column 1
Class.SBQQ.QuoteCalculator.initDiscountSchedules: line 83, column 1
Class.SBQQ.QuoteCalculator.: line 47, column 1
Class.SBQQ.QuoteCalculatorFactory.newQuoteCalculator: line 33, column
1 Class.SBQQ.QuoteCalculatorFactory.newQuoteCalculator: line 26,
column 1 Class.SBQQ.QuoteService.calculate: line 324, column 1
Class.SBQQ.QuoteService.calculate: line 261, column 1
Class.SBQQ.QuoteService.calculate: line 257, column 1
Class.SBQQ.QuoteService.calculateAndSynch: line 204, column 1
Class.SBQQ.QuoteService.processLineTriggerAfter: line 1158, column 1
Trigger.SBQQ.QuoteLineAfter: line 12, column 1: []
Test Class
The 'insert' on the quote lines objects is what is throwing the error listed above.
@isTest
private class QuoteLineListCtrl_Test {
private static Integer QUOTE_LINE_ITEM_COUNT = 50;
@TestSetup
private static void setup(){
Account account = (Account) SmartFactory.createSObject('Account');
insert account;
Contact contact = (Contact) SmartFactory.createSObject('Contact');
insert contact;
Id pricebookId = Test.getStandardPricebookId();
Opportunity opportunity = (Opportunity) SmartFactory.createSObject('Opportunity');
opportunity.AccountId = account.Id;
insert opportunity;
opportunity.Pricebook2Id = pricebookId;
update opportunity;
Product2 product = (Product2) SmartFactory.createSObject('Product2');
insert product;
SBQQ__Cost__c cost = new SBQQ__Cost__c();
cost.SBQQ__Product__c = product.Id;
cost.SBQQ__UnitCost__c = 100;
insert cost;
PricebookEntry pricebookEntry = new PricebookEntry();
pricebookEntry.Pricebook2Id = pricebookId;
pricebookEntry.Product2Id = product.Id;
pricebookEntry.IsActive = true;
pricebookEntry.UnitPrice = 100;
insert pricebookEntry;
SBQQ__Quote__c quote = new SBQQ__Quote__c();
quote.SBQQ__Account__c = account.Id;
quote.SBQQ__Opportunity2__c = opportunity.Id;
quote.SBQQ__PrimaryContact__c = contact.Id;
quote.SBQQ__Primary__c = TRUE;
quote.Final_Signature_Date__c = Date.today();
insert quote;
List<SBQQ__QuoteLine__c> quoteLineItems = new List<SBQQ__QuoteLine__c>();
for(Integer i = 0; i < QUOTE_LINE_ITEM_COUNT; i++){
SBQQ__QuoteLine__c quoteLineItem = new SBQQ__QuoteLine__c();
quoteLineItem.SBQQ__Quote__c = quote.Id;
quoteLineItem.SBQQ__Quantity__c = 1;
quoteLineItem.SBQQ__RegularPrice__c = 100;
quoteLineItem.SBQQ__CustomerPrice__c = 50;
quoteLineItem.SBQQ__Cost__c = cost.Id;
quoteLineItems.add(quoteLineItem);
}
insert quoteLineItems;
}
@isTest
private static void queryQuoteLines() {
SBQQ__Quote__c quote = [SELECT Id FROM SBQQ__Quote__c LIMIT 1];
Test.startTest();
List<SBQQ__QuoteLine__c> quoteLineItems = QuoteLineListCtrl.queryQuoteLines(quote.Id);
Test.stopTest();
System.assertEquals(null, quoteLineItems);
System.assertEquals(QUOTE_LINE_ITEM_COUNT, quoteLineItems.size());
}
}
Best Answer
If you didn't figure this out yet, you need to add the SBQQ__Product__c lookup field value to your quote line.