function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Manju053Manju053 

Help required to write Test Class for below Trigger

Hello Developers

I have been trying to write test class for the Below trigger, the Trigger basically syncs products from quote line items to opportunity line items, when custom checkbox is checked, i have designed a test class, but when i click run test, the code coverage shows 0, below is my trigger and tets class 

Trigger
 
trigger QuoteLineItemTrigger on Quotes__c (after insert, after update)
{
    
    Map<Id,Id> quoteIdToOppId =new Map<Id,Id>();
    Map<Id,List<QuoteLineitem__c>> quoteIdToLineItems = new Map<Id,List<QuoteLineitem__c>>();
    List<OpportunityLineItem__c> oppLineItems = new List<OpportunityLineItem__c>();
    Map<Id,String> oppIdtoName = new Map<Id,String>();
    
    for(Quotes__c q : trigger.new)
    {
        if(q.IsSyncing__c && q.IsSyncing__c  != Trigger.oldMap.get(q.Id).IsSyncing__c ) quoteIdToOppId.put(q.id, q.OpportunityId__c);
    }
    System.debug('UAC: quoteIdToOppId ' + quoteIdToOppId);
    
    for( QuoteLineitem__c qli :[SELECT Id, Product2Id__c,Product2Id__r.name,Quantity__c,ServiceDate__c, QuotesId__c,ListPrice__c,Line_Item_Description__c,Total_Price__c,Product2Id__r.Product_Code__c,UnitPrice__c  FROM QuoteLineitem__c WHERE QuotesId__c =:quoteIdToOppId.keyset() ])
    {
        List<QuoteLineitem__c> tempList = quoteIdToLineItems.get(qli.QuotesId__c) ;
        if(tempList == null)
        {
            
            templist = new List<QuoteLineitem__c>();
            quoteIdToLineItems.put(qli.QuotesId__c, templist);
           
        }
        tempList.add(qli);
    }
    System.debug('UAC: quoteIdToLineItems ' + quoteIdToLineItems);
    
    for(Opportunities__c opp : [SELECT Id , Name  FROM Opportunities__c WHERE ID IN :quoteIdToOppId.values()] )
    
    {
        oppIdtoName.put(opp.id, opp.Name)   ;
    }
    System.debug('UAC: oppIdtoName ' + quoteIdToLineItems);
    
    for(Quotes__c q : Trigger.new)
    {
        if(q.IsSyncing__c && quoteIdToLineItems.containsKey(q.Id))
        {
            for(QuoteLineitem__c qli : quoteIdToLineItems.get(q.Id))
            {
                OpportunityLineItem__c oli = new OpportunityLineItem__c();
                oli.OpportunityId__c = quoteIdToOppId.get(qli.QuotesId__c); 
                System.debug(' qli.Product2Id__r.name ' +  qli.Product2Id__r.name);
                oli.Name = qli.Product2Id__r.name;
                System.debug(' qli.Product2Id__c ' +  qli.Product2Id__c);
                System.debug(' qli.ListPrice__c ' +  qli.ListPrice__c);
                System.debug(' qli.Line_Item_Description__c ' +  qli.Line_Item_Description__c);
                oli.Product2Id__c = qli.Product2Id__c; 
                oli.Quantity__c = qli.Quantity__c; 
                oli.ListPrice__c = integer.valueof(qli.ListPrice__c); 
                oli.Description__c = qli.Line_Item_Description__c;
                oli.ServiceDate__c = qli.ServiceDate__c;
                oli.Total_Price__c = qli.Total_Price__c;
                oli.ProductCode__c = qli.Product2Id__r.Product_Code__c;
                oli.Sales_Price__c =qli.UnitPrice__c;
                oppLineItems.add(oli);
            }
            
        }
        System.debug('UAC: oppLineItems ' + oppLineItems);
        if(oppLineItems.size() > 0) insert oppLineItems ;
        
    }
}

My test Class

 
@isTest(SeeAllData=true)
public class QuoteLineItemTestClass {							
    
    
    private static void setUpData(){
        
        Opportunities__c opp = new Opportunities__c();
        opp.Name = 'Test Opp';
        opp.Stage__c = 'Prospecting';
        opp.Close_Date__c = Date.today();
        insert opp;
        
        Quotes__c Quo = new Quotes__c();
        Quo.Name = 'Test Quote';
        Quo.OpportunityId__c = opp.Id;
        Quo.AccountId__c = opp.Id;
        insert Quo;
        
        QuoteLineitem__c QLI = new QuoteLineitem__c();
        QLI.QuotesId__c = Quo.Id;
        QLI.Quantity__c = 1;
        QLI.Product2Id__c = Quo.Id;
        insert QLI;
        
        Product2__c P = new Product2__c();
        P.Name = 'Test record';
        P.Opportunities__c = opp.Id;
        insert P;
        
        PricebookEntry__c PBE = new PricebookEntry__c();
        PBE.Product2Id__c = p.Id;
        PBE.IsActive__c = true;
        insert PBE;
        
        Pricebook2__c pb = [select Id from Pricebook2__c where Is_Standard_Price_Book__c = true limit 1]; 
        
    }
    
    static testMethod void  basicTest() {
       
    QuoteLineitem qli = [Select Id,QuoteId From QuoteLineitem Limit 1];
        Test.startTest();
            Insert qli;
        Test.stopTest();                
    }
}
Best Answer chosen by Manju053
Andrew GAndrew G
Ok,
so Force.com answers some questions. Cool. 
As for the test code, some things still don't ring, so lets build the test data logically.  So build the pricebooks then products, before Account > Oppty > Quote > Quote Line Item.

Then for our test, grab the data that was created and do a simple update. We can then play with asserts later, but keep in mind that we should do some.

Try the reformat below, fix any syntax errors (done this in a simple text editor) and see how it goes.

Regards
Andrew
@isTest
public class QuoteLineItemTestClass {

    @TestSetup
    private static void setUpData(){
        Id pricebookId = Test.getStandardPricebookId();

        Pricebook2 customPB = new Pricebook2(Name='Standard Price Book', isActive=true);
        insert customPB;

        Product2__c prod = new Product2__c();
        prod.Name = 'Test product';
        insert P;

        PricebookEntry pricebookentry = new PricebookEntry(
                Pricebook2Id = pricebookId, Product2Id = p.Id,
                UnitPrice = 0.0, IsActive = true);
        insert pricebookentry;

        PricebookEntry__c PBE = new PricebookEntry__c();
        PBE.Product2Id__c = p.Id;
        PBE.IsActive__c = true;
        insert PBE;

        Account acc= new Account();
        acc.Name='test';
        insert acc;

        Opportunities__c opp = new Opportunities__c();
        opp.Name = 'Test Opp';
        opp.Stage__c = 'Prospecting';
        opp.Close_Date__c = Date.today();
        insert opp;

        Quotes__c Quo = new Quotes__c();
        Quo.Name = 'Test Quote';
        Quo.OpportunityId__c = opp.Id;
        Quo.AccountId__c = acc.Id;
        insert Quo;

        QuoteLineitem__c QLI = new QuoteLineitem__c();
        QLI.QuotesId__c = Quo.Id;
        QLI.Quantity__c = 1;
        QLI.Product2__c = product.Id;   //check this for syntax
        insert QLI;

    }

    static testMethod void  basicTest() {
        //get the basic quote we setup in test
        Quotes__c = testQuote = [SELECT Id, IsSyncing FROM Quotes__c WHERE Name = 'Test Quote'];

//start the test now - helps reset the limits count etc...
        Test.startTest();
        testQuote.IsSyncing__c=true;
        update quo;

        Test.stopTest();
        
//now do some asserts
        Opportunities__c testOpp = [ SELECT Id FROM Opportunities__c WHERE Name = 'Test Opp' LIMIT 1];
        
        List<OpportunityLineItems> opptyLIs = [SELECT Id, Product2__c FROM OpportunityLineItem WHERE OpportunityId = :testOpp.Id];
        System.assertEquals(1, opptyLIs.size());  //sanity check for one entry
        System.assertsEquals(product.Id, OpptyLIs[0].Product2__c);  //or whatever syntax works.
        
    }
}

 

All Answers

Andrew GAndrew G

Hi

As I read your code,

1. It seems that you have a custom version of all the standard quoting objects.     Product2__c v Product2, Opportunities__c v Opportunity

Is this correct?

2. You have tagged your test class as public.  Is there a reason for that?

3. You are using (SeeAllData) with a TestSetup.  Why?  they are counterproductive and using SeeAllData is not best practice

4.  You have not tagged your setUpData() as @TestSetup.

5. Biggest issue -  you have a trigger for an object Quotes__c, yet your test method simply retrieves and inserts a QuoteLineItem object.  I note that there is an insert of the Quote__c during the test setup, so i'm surprised that does at least cause the trigger to fire and provide some coverage.

6. And i'm surprised that your Insert qli; line does not raise an error regarding inserting a record with an existing Id.

Regards
Andrew

Manju053Manju053
@Andrew G
1. Yes since i am doing the project in  Force.com, i have built everything in the custom object
2.I refered from the salesforce stackoverflow fourm website
3.yes you are correct, this is not a best pratice, i have removed the (SeeAllData)
4.Yes i have corrected that
5. Yes there is mistake in the code, actually it should be QuoteLineitem__c, i think i will remove that
6.ok i will remove that and check again

So what else should i do 

below is my updated test class

@isTest
 public class QuoteLineItemTestClass {                            
    
    @TestSetup
    private static void setUpData(){
        Account acc= new Account();  
        acc.Name='test';
        insert acc;
        
        Opportunities__c opp = new Opportunities__c();
        opp.Name = 'Test Opp';
        opp.Stage__c = 'Prospecting';
        opp.Close_Date__c = Date.today();
        insert opp;
        Date closeDt = Date.Today();
        
        List<String> selectedProducts =new List<String>();
        date myDate = date.today();
        List<Product2> listProd = new List<Product2>();
        Product2 prod=new Product2(Name='Radio');
        listProd.add(prod);
        insert listProd;
      
        Id pricebookId = Test.getStandardPricebookId();
        List<PriceBookEntry> listStdPrice = new List<PriceBookEntry>();
        PricebookEntry pricebOkkStandard = new PricebookEntry(
            Pricebook2Id = pricebookId, Product2Id = prod.Id,
            UnitPrice = 0.0, IsActive = true);
         listStdPrice.add(pricebOkkStandard);
        insert listStdPrice;

     
        Pricebook2 customPB = new Pricebook2(Name='Standard Price Book', isActive=true);
        insert customPB;
        Quotes__c Quo = new Quotes__c();
        Quo.Name = 'Test Quote';
        
        Quo.OpportunityId__c = opp.Id;
        Quo.AccountId__c = acc.Id;
        insert Quo;
        
        QuoteLineitem__c QLI = new QuoteLineitem__c();
        QLI.QuotesId__c = Quo.Id;
        QLI.Quantity__c = 1;
  
        insert QLI;
        
        Product2__c P = new Product2__c();
        P.Name = 'Test record';
        P.Opportunities__c = opp.Id;
        insert P;
        
        PricebookEntry__c PBE = new PricebookEntry__c();
        PBE.Product2Id__c = p.Id;
        PBE.IsActive__c = true;
        insert PBE;
        quo.IsSyncing__c=true;
        update quo;
    }
    
    static testMethod void  basicTest() {
        
        Test.startTest();
        setUpData();
        Test.stopTest();                
    }
}
 
Andrew GAndrew G
Ok,
so Force.com answers some questions. Cool. 
As for the test code, some things still don't ring, so lets build the test data logically.  So build the pricebooks then products, before Account > Oppty > Quote > Quote Line Item.

Then for our test, grab the data that was created and do a simple update. We can then play with asserts later, but keep in mind that we should do some.

Try the reformat below, fix any syntax errors (done this in a simple text editor) and see how it goes.

Regards
Andrew
@isTest
public class QuoteLineItemTestClass {

    @TestSetup
    private static void setUpData(){
        Id pricebookId = Test.getStandardPricebookId();

        Pricebook2 customPB = new Pricebook2(Name='Standard Price Book', isActive=true);
        insert customPB;

        Product2__c prod = new Product2__c();
        prod.Name = 'Test product';
        insert P;

        PricebookEntry pricebookentry = new PricebookEntry(
                Pricebook2Id = pricebookId, Product2Id = p.Id,
                UnitPrice = 0.0, IsActive = true);
        insert pricebookentry;

        PricebookEntry__c PBE = new PricebookEntry__c();
        PBE.Product2Id__c = p.Id;
        PBE.IsActive__c = true;
        insert PBE;

        Account acc= new Account();
        acc.Name='test';
        insert acc;

        Opportunities__c opp = new Opportunities__c();
        opp.Name = 'Test Opp';
        opp.Stage__c = 'Prospecting';
        opp.Close_Date__c = Date.today();
        insert opp;

        Quotes__c Quo = new Quotes__c();
        Quo.Name = 'Test Quote';
        Quo.OpportunityId__c = opp.Id;
        Quo.AccountId__c = acc.Id;
        insert Quo;

        QuoteLineitem__c QLI = new QuoteLineitem__c();
        QLI.QuotesId__c = Quo.Id;
        QLI.Quantity__c = 1;
        QLI.Product2__c = product.Id;   //check this for syntax
        insert QLI;

    }

    static testMethod void  basicTest() {
        //get the basic quote we setup in test
        Quotes__c = testQuote = [SELECT Id, IsSyncing FROM Quotes__c WHERE Name = 'Test Quote'];

//start the test now - helps reset the limits count etc...
        Test.startTest();
        testQuote.IsSyncing__c=true;
        update quo;

        Test.stopTest();
        
//now do some asserts
        Opportunities__c testOpp = [ SELECT Id FROM Opportunities__c WHERE Name = 'Test Opp' LIMIT 1];
        
        List<OpportunityLineItems> opptyLIs = [SELECT Id, Product2__c FROM OpportunityLineItem WHERE OpportunityId = :testOpp.Id];
        System.assertEquals(1, opptyLIs.size());  //sanity check for one entry
        System.assertsEquals(product.Id, OpptyLIs[0].Product2__c);  //or whatever syntax works.
        
    }
}

 
This was selected as the best answer
Manju053Manju053
@Andrew G
i worked out perfectly fine, i did some minor configurations and the test coverage shows 100%
 Thanks a lot:)