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
travis.truetttravis.truett 

Test class doesn't work

I posted a question about this yesterday, but didn't get any help...if anyone could just quickly walk me through this, I'd greatly appreciate it. I wrote a trigger that automatically creates revenue schedule items for opportunity products when those opp products are created. I'm trying to move it from the sandbox to my company's instance, but I need to test it first. This is my test class. As of now, it's not working. It's fairly straightforward/simple, which is why I'm confused that it's not working. If you need to see my trigger's source code, just let me know.

@isTest
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();        
OpportunityLineItem oli = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = [select id from PricebookEntry where product2.name='Onboarding' LIMIT 1].id,
        TotalPrice = 1
    );
    oliList.add(oli);
    insert oliList;
    
    System.assertEquals(True, oli.HasRevenueSchedule);
    
  }
    
}
Best Answer chosen by travis.truett
Vivek DeshmaneVivek Deshmane
Hi Travis,
Please try this , now assert shoul work and please mark the best answer.
@isTest (seeAllData=true)
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
    
        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        prod.CanUseRevenueSchedule=true;
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
        pb.Name = 'Test';
        pb.IsActive = true;
        insert pb;
    Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
            
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = standardpb.Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();        
OpportunityLineItem oli = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2
        
    );
    oliList.add(oli);
    insert oliList;
    
    //Your trigger should have OpportunityLineItemSchedule logic then following asert will pass else it will fail
    List<OpportunityLineItem> lstOptyLi =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oli.id];
    System.assertEquals(True, lstOptyLi[0].HasRevenueSchedule);
   
   
  }
    
}
Best Regards,
-Vivek

All Answers

Vivek DeshmaneVivek Deshmane
Could you please share actual error.?

Best Regards,
-Vivek
Vivek DeshmaneVivek Deshmane
Hi travis,
Please try below code and please let me know if it works, Mark best answer.

@isTest (seeAllData=true)
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
    
        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
           pb.Name = 'Test';
           pb.IsActive = true;
        insert pb;
    Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
               
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = standardpb.Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();        
OpportunityLineItem oli = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2
        
    );
    oliList.add(oli);
    insert oliList;
    //Your trigger should have OpportunityLineItemSchedule logic then following asert will pass else it will fail
    System.assertEquals(True, oli.HasRevenueSchedule);
    
  }
    
}
Regards,
-Vivek
travis.truetttravis.truett
Vivek, Thanks so much for getting back to me. I tried your test and got the following error:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, editSchedule: execution of AfterInsert caused by: System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, field integrity exception: unknown (scheduling not enabled on product): [unknown] Trigger.editSchedule: line 129, column 1: []

I'll go ahead and post the editSchedule trigger below. The error is thrown at line 129, where it says "insert listOLIS":

trigger editSchedule on OpportunityLineItem (after insert) {

if(Trigger.isInsert){

Map<Id, Opportunity> opportunities = new Map<Id, Opportunity>();
Date myDate = Date.newInstance(1990, 2, 17);

for(OpportunityLineItem oli: Trigger.new) {
    opportunities.put(oli.OpportunityId, null);
}
opportunities.putAll([SELECT CloseDate FROM Opportunity WHERE Id in :opportunities.keySet()]);
for(OpportunityLineItem oli: Trigger.new) {
     Opportunity thisLineItemOpp = opportunities.get(oli.OpportunityId);
     myDate = thisLineItemOpp.CloseDate;
      // thisLineItemOpp.CloseDate is the close date you're looking for
}

List<OpportunityLineItemSchedule> listOLIS = new List<OpportunityLineItemSchedule>();

ID OnboardingPBE = [select id from PricebookEntry where product2.name='Onboarding' LIMIT 1].id;
ID TrainingPBE = [select id from PricebookEntry where product2.name='Training' LIMIT 1].id;

for (OpportunityLineItem oli: Trigger.new){

if(oli.PricebookEntryId == OnboardingPBE || oli.PricebookEntryId == TrainingPBE){//These are the Pricebook Entry IDs of Onboarding and Training, our two services. 
                                                                                           //They must be handled differently than the products, because their list price 
                                                                                           //is one sum, as opposed to a monthly amount. In order to get this trigger to handle
                                                                                           //new services, insert their IDs into each if statement for handling services.    

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = 943, ScheduleDate = myDate, Type = 'Revenue'));

}


    if(oli.Payment_Terms__c == 'Monthly'){
    
    if(oli.PricebookEntryId == OnboardingPBE || oli.PricebookEntryId == TrainingPBE){
    
for(Integer duration = (Integer)oli.Duration__c; duration > 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = (oli.Discounted_Price__c*oli.Quantity)/oli.Duration__c, ScheduleDate = myDate, Type = 'Revenue'));
myDate = myDate.addMonths(1);

}//end of loop
    
    }//end of inner IF
    
else{
for(Integer duration = (Integer)oli.Duration__c; duration > 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = oli.Discounted_Price__c*oli.Quantity, ScheduleDate = myDate, Type = 'Revenue'));
myDate = myDate.addMonths(1);

}//end of loop

}//end of else

}//end of Monthly IF


    else if(oli.Payment_Terms__c == 'Quarterly'){
    
         if(oli.PricebookEntryId == OnboardingPBE || oli.PricebookEntryId == TrainingPBE){
    
for(Integer duration = (Integer)oli.Duration__c/3; duration > 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = (oli.Discounted_Price__c*oli.Quantity*3)/oli.Duration__c, ScheduleDate = myDate, Type = 'Revenue'));
myDate = myDate.addMonths(3);

}//end of loop
    
    }//end of inner IF

else{
for(Integer duration = (Integer)oli.Duration__c/3; duration > 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = oli.Discounted_Price__c*oli.Quantity*3, ScheduleDate = myDate, Type = 'Revenue'));
myDate = myDate.addMonths(3);

}//end of loop

}//end of else

}//end of Quarterly IF


    else if(oli.Payment_Terms__c == 'Annually'){
    
         if(oli.PricebookEntryId == OnboardingPBE || oli.PricebookEntryId == TrainingPBE){
    
for(Integer duration = (Integer)oli.Duration__c/12; duration > 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = (oli.Discounted_Price__c*oli.Quantity*12)/oli.Duration__c, ScheduleDate = myDate, Type = 'Revenue'));
myDate = myDate.addYears(1);

}//end of loop
    
    }//end of inner IF

else{
for(Integer duration = (Integer)oli.Duration__c/12; duration > 0; duration--){

listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = oli.Discounted_Price__c*oli.Quantity*12, ScheduleDate = myDate, Type = 'Revenue'));
myDate = myDate.addYears(1);

}//end of loop

}//end of else

}//end of Annually IF


    else if(oli.Payment_Terms__c == 'Up Front'){
    
         if(oli.PricebookEntryId == OnboardingPBE || oli.PricebookEntryId == TrainingPBE){
    
listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = oli.Discounted_Price__c*oli.Quantity, ScheduleDate = myDate, Type = 'Revenue'));
  
    }//end of inner IF

else{
listOLIS.add(new OpportunityLineItemSchedule(OpportunityLineItemId = oli.Id, Revenue = oli.Discounted_Price__c*oli.Quantity*oli.Duration__c, ScheduleDate = myDate, Type = 'Revenue'));

}//end of else

}//end of Up Front IF 


insert listOLIS;

}

}//end of isInsert

}//end of trigger
 
Vivek DeshmaneVivek Deshmane
Hi,
Could you please enable the schedule . follow step as below and let me know if it helps you.
Setup==>Product==>Schedule Setup
check Scheduling Enabled checkbox

Best Regards,
-Vivek
travis.truetttravis.truett
I made that change, but am still getting the same error.
Vivek DeshmaneVivek Deshmane
Hi ,
Try this code. it should work.
@isTest (seeAllData=true)
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
    
        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        prod.CanUseRevenueSchedule=true;
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
        pb.Name = 'Test';
        pb.IsActive = true;
        insert pb;
    Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
            
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = standardpb.Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();        
OpportunityLineItem oli = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2
        
    );
    oliList.add(oli);
    insert oliList;
    
    //Your trigger should have OpportunityLineItemSchedule logic then following asert will pass else it will fail
    //System.assertEquals(True, oli.HasRevenueSchedule);
   
   
  }
    
}
Best Regards,
Vivek
travis.truetttravis.truett
It failed in the assert method...what exactly do you mean when you say my trigger should have OpportunityLineItemSchedule logic?
Thanks again for all your help.
Vivek DeshmaneVivek Deshmane
Hi Travis,
Please try this , now assert shoul work and please mark the best answer.
@isTest (seeAllData=true)
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
    
        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        prod.CanUseRevenueSchedule=true;
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
        pb.Name = 'Test';
        pb.IsActive = true;
        insert pb;
    Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
            
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = standardpb.Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();        
OpportunityLineItem oli = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2
        
    );
    oliList.add(oli);
    insert oliList;
    
    //Your trigger should have OpportunityLineItemSchedule logic then following asert will pass else it will fail
    List<OpportunityLineItem> lstOptyLi =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oli.id];
    System.assertEquals(True, lstOptyLi[0].HasRevenueSchedule);
   
   
  }
    
}
Best Regards,
-Vivek
This was selected as the best answer
travis.truetttravis.truett
That worked! My trigger is 45% covered now. Do you have any recommendations for how I can make my test more robust?
Vivek DeshmaneVivek Deshmane
Try below code to boost code coverage.
@isTest (seeAllData=true)
private class testEditSchedule{

static testMethod void testUpdateSchedule() {
 
List<Account> aList = new List<Account>();    
Account a = new Account(
      Name = 'Test Account'
    );
    aList.add(a);
    
    insert aList;
    

List<Opportunity> oList = new List<Opportunity>();
Opportunity o = new Opportunity(
      Name = 'Test Opportunity', 
      StageName = 'Discovery', 
      CloseDate = Date.today(), 
      AccountId = a.Id
    );
    
    oList.add(o);
    insert oList;
    
        //Create Product
        Product2 prod = new Product2();
        prod.IsActive = true;
        prod.Name = 'Onboarding';
        prod.CanUseRevenueSchedule=true;
        insert prod;
        //Create PriceBook
        Pricebook2 pb = new Pricebook2();
        pb.Name = 'Test';
        pb.IsActive = true;
        insert pb;
    Pricebook2 standardpb = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        
            
        PricebookEntry standardpbe = new PricebookEntry();
        standardpbe.Pricebook2Id = standardpb.Id;
        standardpbe.Product2Id = prod.Id;
        standardpbe.UnitPrice = 10000;
        standardpbe.IsActive = true;
        standardpbe.UseStandardPrice = false;
        insert standardpbe;
        
        PricebookEntry pbe = new PricebookEntry();
        pbe.Pricebook2Id = pb.Id;
        pbe.Product2Id = prod.Id;
        pbe.UnitPrice = 10000;
        pbe.IsActive = true;
        pbe.UseStandardPrice = false;
        insert pbe;
        
List<OpportunityLineItem> oliList = new List<OpportunityLineItem>();        
OpportunityLineItem oliAnnually = new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Annually'
        
    );
    OpportunityLineItem oliMonthly= new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Monthly'
        
    );
    OpportunityLineItem oliQuarterly= new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2,
        Payment_Terms__c ='Quarterly'
        
    );
    OpportunityLineItem oli= new OpportunityLineItem(
        OpportunityId = o.Id,  
        PricebookEntryId = pbe.id,
        TotalPrice = 1,
        Quantity=2
        
        
    );
    oliList.add(oliAnnually);
    oliList.add(oliMonthly);
    oliList.add(oliQuarterly);
    oliList.add(oli);
    insert oliList;
    
    //Your trigger should have OpportunityLineItemSchedule logic then following asert will pass else it will fail
    List<OpportunityLineItem> lstOptyLi =[SELECT HasRevenueSchedule from OpportunityLineItem where Id =:oli.id];
    System.assertEquals(True, lstOptyLi[0].HasRevenueSchedule);
   
   
  }
    
}
travis.truetttravis.truett
It failed at line 93 at the insert statement...I'm not sure why. Also, in the select statement, would you need to modify the where part to include the other opportunitylineitem objects?
travis.truetttravis.truett
I commented out all but one of the oliList.add lines, so that only one OpportunityLineItem was being added to the list, and that got it working again, but I want to be able to add all of those different OpportunityLineItems for the sake of coverage...I'm not sure why, but it's throwing a DML error when I try to insert a list with more than just one OpportunityLineItem in it.
travis.truetttravis.truett
I just resorted to making 4 seperate lists, one for each OpportunityLineItem. For some reason, that worked, and bumped my code up to 75% coverage.