My test class requires a quote as an input. Thus, I am creating a quote this way with SeeAllData=true. I'm limiting this by only selecting 1 quote from all my production data. However, it seems that I was lucky enough to pick the one PricebookEntry which does not have a QuoteLineItem. Is there any way to ensure that I choose a PricebookEntry which absolutely has AT LEAST one QuoteLineItem attached to it? I've provided my short test class below.

@isTest (SeeAllData=true)

public with sharing class Test_Quote_Quote_Clone {

    static testMethod void test_Quote_Quote_Clone(){

        List<Product2> validProduct = [SELECT Id,isActive From Product2 WHERE isActive=true];
        list<ID> P2valid = new List<Id>();

        List<PricebookEntry> validPBE = [SELECT ID FROM PricebookEntry WHERE Product2Id IN:P2Valid LIMIT 1];
        List<ID> PBEId = new List<Id>();

        List<QuoteLineItem> newtestQuoteLineItem = [Select QuoteId FROM QuoteLineItem WHERE PricebookEntryId IN:PBEId Limit 1]; 
        List<ID> quoteId = new List<ID>(); 

        List<Quote> newtestQuote = [SELECT Id,OpportunityId,Sales_Manager__c,Name,Sales_Manager_Phone__c,ExpirationDate                       
                                    FROM Quote WHERE ID IN:quoteId LIMIT 1];    

        for(Quote newTestQuote1:newtestQuote){
            ApexPages.StandardController stdController = new ApexPages.StandardController(newTestQuote1);
            Controller_Quote_Quote_Clone tQQC = new Controller_Quote_Quote_Clone(stdController);
            PageReference quoteRef = tQQC.createQuoteClone();
  • 1
    What about getting a Quote first and then getting its pricebook? Can you switch the order around? – Mike Chale Aug 26 '13 at 14:50
  • I'm not sure if that would help? I need to make sure the Product2 that I'm choosing is set to Active as seen in the query. Doing it backwards from Quote, I'm not sure how I could ensure that. – SSadat Aug 26 '13 at 14:56
  • Hraefn's answer explains what I meant. – Mike Chale Aug 26 '13 at 15:01
  • Really, be weary of using SeeAllData=true. It shouldn't be too difficult to create your own test data, and if you do, then you'll waste no time worrying that there exists ample data out there so your test always passes. And if it is difficult to create test data, take the effort and write some methods that create your test data. Sure it's a pain at the moment, but then you'll never, ever have to think about having to create 'em again. – Scott Pelak Aug 26 '13 at 15:41
  • That's great advice and it is what we usually do. However, we seem to run into this issue everytime we try to test a class that makes use of a Quote and so far the SeeAllData=true seems to be the only way to test that out. – SSadat Aug 26 '13 at 19:12

There's no need to depend on organization data, and this just a Bad Idea™. Instead, create a new product, attach it to the standard price book, create a new opportunity with the standard price book, then create a new quote, and finally, a new quote line item. Regrettably, you still need SeeAllData for the price book. Example forthwith:

Product2 pr = new Product2(Name='test',IsActive=true);
insert pr;
Pricebook2 stdpb = [select id,isactive from pricebook2 where isstandard=true];
if(!stdpb.isactive) {
    stdpb.isactive = true;
    update stdpb;
pricebookentry pbe = new pricebookentry(product2id=pr.id, pricebook2id=stdpb.id, unitprice=9.99, isactive=true, usestandardprice=false);
insert pbe;
account ac = new account(name='test');
insert ac;
opportunity op = new opportunity(name='test', accountid=ac.id, pricebook2id=stdpb.id, closedate=date.today(), stagename='test', probability=0);
insert op;
quote qu = new quote(opportunityid=op.id, pricebook2id=stdpb.id, name='test');
insert qu;
quotelineitem qi = new quotelineitem(quoteid=qu.id, pricebookentryid=pbe.id, quantity=1, unitprice=9.99);
insert qi;

One way to guarantee a child would be to query against the child object.

SELECT PricebookEntry.ID FROM QuoteLineItem
WHERE PricebookEntry.Product2Id IN:P2Valid LIMIT 1
  • List<QuoteLineItem> validPBE1 = [SELECT Id,PricebookEntry.ID FROM QuoteLineItem WHERE PricebookEntry.Product2Id IN:P2Valid LIMIT 1]; List<ID> PBEId = new List<Id>(); PBEId.add(validPBE1.get(0).PricebookEntry.Id); List<QuoteLineItem> newtestQuoteLineItem = [Select QuoteId FROM QuoteLineItem WHERE ID IN:PBEId Limit 1]; Unless I'm mistaken, is that what you meant? Because I've tried that and I still get the list index out of Bounds error when I try to create a newtestQuote. – SSadat Aug 26 '13 at 15:11
  • You would need to identify which query is returning no results and address from there; that said, sfdcfox has the best answer. – Hraefn Aug 26 '13 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.