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
Shaun B.Shaun B. 

Why is my code coverage only 64%?

I'm a newbie for APEX and I'm trying to redeploy a fix for a former APEX trigger we had already deployed to production.  When I try to deploy it, I get it shows Code Coverage as 64% (9/14) and won't let me deploy.  Can someone please let me know what I'm doing wrong?

Apex Trigger:
trigger UpdatePricing on OpportunityLineItem (before insert, before update) {


Map<String, List<Volume_Discount__c>> PricingMap = new Map<String, List<Volume_Discount__c>>();
for(Volume_Discount__c  P : [SELECT ID,Minimum_Quantity__c,Product__c,Price_Book__c  FROM Volume_Discount__c ORDER BY Minimum_Quantity__c])
{
  if(PricingMap.KeySet().contains(P.Product__c+'|'+P.Price_Book__c))
  {   
     PricingMap.get(P.Product__c+'|'+P.Price_Book__c).add(P);
  }
  else
  {
     PricingMap.put(P.Product__c+'|'+P.Price_Book__c,new List<Volume_Discount__c> {P});
  }
}


for(OpportunityLineItem  oli : Trigger.new)
{
oli.Volume_Discount__c = null;
if(PricingMap.KeySet().contains(oli.Product2Id+'|'+oli.Opportuity_PriceBook2__c) && oli.ProductAndPriceBookActive__c)
{
    for(Volume_Discount__c P : PricingMap.get(oli.Product2Id+'|'+oli.Opportuity_PriceBook2__c))
    {
        if(oli.quantity >= P.Minimum_Quantity__c)
        {
           oli.Volume_Discount__c = P.ID;
        }
    }
}

}


}

Apex Class:
@isTest
Public class UpdatePricingTest{


Public static testmethod void testing(){
integer def = 0;
list<OpportunityLineitem  > olitoupdate = new list<OpportunityLineitem  >();
for(OpportunityLineitem  oli : [SELECT ID,Quantity from OpportunityLineItem  order by createddate desc LIMIT 5]){
OLI.Quantity = def +200;
olitoupdate.add(OLI);
}
if(olitoupdate.size()>0){
update olitoupdate;
}


PriceBook2 PB = new PriceBook2();
PB.Name = 'New Pricebook';
PB.isactive = true;
insert PB;

Product2 pro = new Product2();
pro.Name = 'Prod';
pro.Billing_Type__c = 'Financed';
insert pro;


insert new PriceBookEntry(Product2Id=pro.Id, Pricebook2Id=Test.getStandardPricebookId(), UnitPrice=0);


PricebookEntry  PBE = new PricebookEntry();
PBE.Product2ID = Pro.ID;
PBE.PriceBook2ID = PB.ID;
PBE.UnitPrice = 120;
PBE.Isactive = true;
insert PBE;


Volume_Discount__c Pricing = new Volume_Discount__c();
Pricing.Minimum_Quantity__c = 100;
Pricing.Product__c = Pro.ID;
Pricing.Price_Book__c  = PB.ID;
Pricing.Annual_Overage__c = 2.5;
Pricing.Annual_Price__c = 2.5;
Pricing.Quarterly_Overage__c = 2.5;
Pricing.Quarterly_Price__c = 2.5;
Pricing.Monthly_Overage__c = 2.5;
Pricing.Monthly_Price__c = 2.5;
insert Pricing;

Account acc = new Account(Name = 'Test Account1');
acc.BillingState = 'TX';
acc.AccountSource = 'Inbound Call';
acc.Industry = 'Bank';
insert acc;

Opportunity Opp = new Opportunity();
Opp.Name = 'Test Opp';
Opp.StageName = 'Interview';
Opp.PriceBook2ID = PB.ID;
Opp.CloseDate = Date.TODAY()-10;
Opp.AccountID = acc.ID;
Opp.Testing__c = true;
insert Opp;

OpportunityLineItem OLI = new OpportunityLineItem();
OLI.OpportunityID = Opp.ID;
OLI.PriceBookEntryID = PBE.ID;
OLI.Quantity = 100;
OLI.Volume_Discount__c = Pricing.ID;
insert OLI;

OLI.Quantity = 99;
update OLI;

}

}

 
Best Answer chosen by Shaun B.
Jithin U NairJithin U Nair
Hi Bailey,

Not sure about the business scenario you are trying to achieve in this trigger but if you are looking to get the coverage then you have to set ProductAndPriceBookActive__c  as true and assign Product2Id,Opportuity_PriceBook2__c for OpportunityLineItem.
 
@isTest
Public class UpdatePricingTest{


Public static testmethod void testing(){
integer def = 0;
list<OpportunityLineitem  > olitoupdate = new list<OpportunityLineitem  >();
for(OpportunityLineitem  oli : [SELECT ID,Quantity from OpportunityLineItem  order by createddate desc LIMIT 5]){
OLI.Quantity = def +200;
olitoupdate.add(OLI);
}
if(olitoupdate.size()>0){
update olitoupdate;
}


PriceBook2 PB = new PriceBook2();
PB.Name = 'New Pricebook';
PB.isactive = true;
insert PB;

Product2 pro = new Product2();
pro.Name = 'Prod';
pro.Billing_Type__c = 'Financed';
insert pro;


insert new PriceBookEntry(Product2Id=pro.Id, Pricebook2Id=Test.getStandardPricebookId(), UnitPrice=0);


PricebookEntry  PBE = new PricebookEntry();
PBE.Product2ID = Pro.ID;
PBE.PriceBook2ID = PB.ID;
PBE.UnitPrice = 120;
PBE.Isactive = true;
insert PBE;


Volume_Discount__c Pricing = new Volume_Discount__c();
Pricing.Minimum_Quantity__c = 100;
Pricing.Product__c = Pro.ID;
Pricing.Price_Book__c  = PB.ID;
Pricing.Annual_Overage__c = 2.5;
Pricing.Annual_Price__c = 2.5;
Pricing.Quarterly_Overage__c = 2.5;
Pricing.Quarterly_Price__c = 2.5;
Pricing.Monthly_Overage__c = 2.5;
Pricing.Monthly_Price__c = 2.5;
insert Pricing;

Account acc = new Account(Name = 'Test Account1');
acc.BillingState = 'TX';
acc.AccountSource = 'Inbound Call';
acc.Industry = 'Bank';
insert acc;

Opportunity Opp = new Opportunity();
Opp.Name = 'Test Opp';
Opp.StageName = 'Interview';
Opp.PriceBook2ID = PB.ID;
Opp.CloseDate = Date.TODAY()-10;
Opp.AccountID = acc.ID;
Opp.Testing__c = true;
insert Opp;

OpportunityLineItem OLI = new OpportunityLineItem();
OLI.OpportunityID = Opp.ID;
OLI.PriceBookEntryID = PBE.ID;
OLI.Quantity = 100;
OLI.TotalPrice=10;
OLI.Volume_Discount__c = Pricing.ID;
insert OLI;
OLI.Quantity = 99;
update OLI;
    
OpportunityLineItem OLI2 = new OpportunityLineItem();
OLI2.OpportunityID = Opp.ID;
OLI2.PriceBookEntryID = PBE.ID;
OLI2.Opportuity_PriceBook2__c=PB.ID;
OLI2.Quantity = 100;
OLI2.TotalPrice=10;
OLI2.Volume_Discount__c = Pricing.ID;
OLI2.ProductAndPriceBookActive__c =true;
OLI2.Product2Id=Pro.ID;
insert OLI2;
OLI2.Quantity = 99;
update OLI2; 
    
}

}

 

All Answers

Jithin U NairJithin U Nair
Hi Bailey,

Not sure about the business scenario you are trying to achieve in this trigger but if you are looking to get the coverage then you have to set ProductAndPriceBookActive__c  as true and assign Product2Id,Opportuity_PriceBook2__c for OpportunityLineItem.
 
@isTest
Public class UpdatePricingTest{


Public static testmethod void testing(){
integer def = 0;
list<OpportunityLineitem  > olitoupdate = new list<OpportunityLineitem  >();
for(OpportunityLineitem  oli : [SELECT ID,Quantity from OpportunityLineItem  order by createddate desc LIMIT 5]){
OLI.Quantity = def +200;
olitoupdate.add(OLI);
}
if(olitoupdate.size()>0){
update olitoupdate;
}


PriceBook2 PB = new PriceBook2();
PB.Name = 'New Pricebook';
PB.isactive = true;
insert PB;

Product2 pro = new Product2();
pro.Name = 'Prod';
pro.Billing_Type__c = 'Financed';
insert pro;


insert new PriceBookEntry(Product2Id=pro.Id, Pricebook2Id=Test.getStandardPricebookId(), UnitPrice=0);


PricebookEntry  PBE = new PricebookEntry();
PBE.Product2ID = Pro.ID;
PBE.PriceBook2ID = PB.ID;
PBE.UnitPrice = 120;
PBE.Isactive = true;
insert PBE;


Volume_Discount__c Pricing = new Volume_Discount__c();
Pricing.Minimum_Quantity__c = 100;
Pricing.Product__c = Pro.ID;
Pricing.Price_Book__c  = PB.ID;
Pricing.Annual_Overage__c = 2.5;
Pricing.Annual_Price__c = 2.5;
Pricing.Quarterly_Overage__c = 2.5;
Pricing.Quarterly_Price__c = 2.5;
Pricing.Monthly_Overage__c = 2.5;
Pricing.Monthly_Price__c = 2.5;
insert Pricing;

Account acc = new Account(Name = 'Test Account1');
acc.BillingState = 'TX';
acc.AccountSource = 'Inbound Call';
acc.Industry = 'Bank';
insert acc;

Opportunity Opp = new Opportunity();
Opp.Name = 'Test Opp';
Opp.StageName = 'Interview';
Opp.PriceBook2ID = PB.ID;
Opp.CloseDate = Date.TODAY()-10;
Opp.AccountID = acc.ID;
Opp.Testing__c = true;
insert Opp;

OpportunityLineItem OLI = new OpportunityLineItem();
OLI.OpportunityID = Opp.ID;
OLI.PriceBookEntryID = PBE.ID;
OLI.Quantity = 100;
OLI.TotalPrice=10;
OLI.Volume_Discount__c = Pricing.ID;
insert OLI;
OLI.Quantity = 99;
update OLI;
    
OpportunityLineItem OLI2 = new OpportunityLineItem();
OLI2.OpportunityID = Opp.ID;
OLI2.PriceBookEntryID = PBE.ID;
OLI2.Opportuity_PriceBook2__c=PB.ID;
OLI2.Quantity = 100;
OLI2.TotalPrice=10;
OLI2.Volume_Discount__c = Pricing.ID;
OLI2.ProductAndPriceBookActive__c =true;
OLI2.Product2Id=Pro.ID;
insert OLI2;
OLI2.Quantity = 99;
update OLI2; 
    
}

}

 
This was selected as the best answer
Shaun B.Shaun B.
Thanks Jithin for your reply!

I tried the code above, but it wouldn't allow me to add lines 78 and 83.  It did compile however with line 82.  My new issue is another trigger that is causing a Too many SOQL queries: 101 error.  Is there a way to prevent that error from occuring?  It seems to be happening from a trigger on the Opportunity object.
Shaun B.Shaun B.
Sorry, mean't to say, "It did compile with line 84".
Shaun B.Shaun B.
@jithin,

I was able to finally get it to compile using the following, but I'm still getting 64% code coverage.  Any other ideas?
 
@isTest
Public class UpdatePricingTest{


Public static testmethod void testing(){
integer def = 0;
list<OpportunityLineitem  > olitoupdate = new list<OpportunityLineitem  >();
for(OpportunityLineitem  oli : [SELECT ID,Quantity from OpportunityLineItem  order by createddate desc LIMIT 5]){
OLI.Quantity = def +200;
olitoupdate.add(OLI);
}
if(olitoupdate.size()>0){
update olitoupdate;
}


PriceBook2 PB = new PriceBook2();
PB.Name = 'New Pricebook';
PB.isactive = true;
insert PB;

Product2 pro = new Product2();
pro.Name = 'Prod';
pro.Billing_Type__c = 'Financed';
insert pro;


insert new PriceBookEntry(Product2Id=pro.Id, Pricebook2Id=Test.getStandardPricebookId(), UnitPrice=0);


PricebookEntry  PBE = new PricebookEntry();
PBE.Product2ID = Pro.ID;
PBE.PriceBook2ID = PB.ID;
PBE.UnitPrice = 120;
PBE.Isactive = true;
insert PBE;


Volume_Discount__c Pricing = new Volume_Discount__c();
Pricing.Minimum_Quantity__c = 100;
Pricing.Product__c = Pro.ID;
Pricing.Price_Book__c  = PB.ID;
Pricing.Annual_Overage__c = 2.5;
Pricing.Annual_Price__c = 2.5;
Pricing.Quarterly_Overage__c = 2.5;
Pricing.Quarterly_Price__c = 2.5;
Pricing.Monthly_Overage__c = 2.5;
Pricing.Monthly_Price__c = 2.5;
insert Pricing;

Account acc = new Account(Name = 'Test Account1');
acc.BillingState = 'TX';
acc.AccountSource = 'Inbound Call';
acc.Industry = 'Bank';
insert acc;

Opportunity Opp = new Opportunity();
Opp.Name = 'Test Opp';
Opp.StageName = 'Interview';
Opp.PriceBook2ID = PB.ID;
Opp.CloseDate = Date.TODAY()-10;
Opp.AccountID = acc.ID;
Opp.Testing__c = true;
insert Opp;

OpportunityLineItem OLI = new OpportunityLineItem();
OLI.OpportunityID = Opp.ID;
OLI.PriceBookEntryID = PBE.ID;
OLI.Quantity = 100;
OLI.TotalPrice=10;
OLI.Volume_Discount__c = Pricing.ID;
insert OLI;
    
OpportunityLineItem OLI2 = new OpportunityLineItem();
OLI2.OpportunityID = Opp.ID;
OLI2.PriceBookEntryID = PBE.ID;
OLI2.Quantity = 100;
OLI2.TotalPrice=10;
OLI2.Volume_Discount__c = Pricing.ID;
OLI2.Product2Id=Pro.ID;
insert OLI2;

OLI2.Quantity = 99;
update OLI2; 
    
}

}

 
Jithin U NairJithin U Nair
Still you are not setting the value for ProductAndPriceBookActive__c for OpportunityLineItem, that is getting validated inside your trigger(UpdatePricing) on line number 21.

You need to cover that statements under that logical section to get more test coverage and for that you need to set value for ProductAndPriceBookActive__c.

Please check the documentation to get more details on Testing and Code Coverage (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_code_coverage_intro.htm) for Apex.


 
Jithin U NairJithin U Nair
Test Coverage
Shaun B.Shaun B.
Yep, I see that in the Developer Console, but the issue is that I can't save those two entries in my class.  When I try to save the code you had originally provided, I get two errors:

Error: Compile Error: Field is not writeable: OpportunityLineItem.Opportuity_PriceBook2__c at line 79 column 6
Error: Compile Error: Field is not writeable: OpportunityLineItem.ProductAndPriceBookActive__c at line 83 column 6

Do you know how I can set those fields if SF is saying they are not writeable?

Thanks Jithin for your continued help.   I really appreciate it!
Jithin U NairJithin U Nair
Are these fields formula fields?If then we cannot assign values in them.
Can you please share the field details?
Shaun B.Shaun B.
Argh!  Thanks for your help and your patience with me.  Turns out those WERE formula fields the whole time... :facepalm:

I adjusted my logic on those fields to include an "OR(Test__c = TRUE)" and set the test fields in my Class to "TRUE" which gave me 92% coverage.

Thanks again Jithin!