You need to sign in to do that
Don't have an account?
sandy k
How to write test coverage for batch class
Hi Guys,
Here is the batch class, how to write test coverage for batch class
public class ServiceBatchable implements Database.Batchable<sObject>, Database.Stateful {
private Id lastJobId = null;
private Id serRecTypeId = null;
public ServiceBatchable () {
}
public Database.QueryLoSeror start(Database.BatchableContext BC) {
Integer limitInt = 10000;
List<AsyncApexJob> aajList = new List<AsyncApexJob>();
if(lastJobId!=null && lastJobId!=BC.getJobId()) {
aajList.addAll([SELECT Id, Status, CompletedDate FROM AsyncApexJob WHERE ID =: lastJobId and JobType!='BatchApexWorker' and Status not in ('Aborted','Completed','Failed')]);
}
if(lastJobId==null || aajList.isEmpty()) {
lastJobId = BC.getJobId();
if(serRecTypeId ==null) {
RecordType rt = opportunityRTMap.get('Service Record');
if(rt!=null) {
serRecTypeId = rt.Id;
}
}
}
if(lastJobId!=BC.getJobId()) {
limitInt = 0;
System.debug('ServiceBatchable: Previous Job alive still - aborting '+BC.getJobId());
}
return Database.getQueryLocator([
select id,CurrencyIsoCode,StageName,Ser_Currency_Code__c,Ser_Line_Item_ID__c,Ser_Duration__c,Ser_Start_Date__c,Ser_Monthly_Amount__c,SER_Updated__c
from Opportunity where
((StageName='1 - Lead' and Ser_Line_Item_ID__c != null) or (StageName!='1 - Lead')) and
SER_Updated__c = true and
External_Id__c != null and
RecordTypeId=: serRecTypeId and
isDeleted=FALSE
limit :limitInt
]);
}
public void execute(Database.BatchableContext BC, List<Opportunity> scope){
Map<Id,OpportunityLineItem> opportunityLineItemMap = new Map<Id,OpportunityLineItem>();
for(OpportunityLineItem oli : [select id,OpportunityId,X2022_Revenue__c,X2023_Revenue__c,Wave__c,UnitPrice,ServiceDate,Seats__c,Quantity,PricebookEntryId,Language__c,FTE__c,Delivery_LoSerion__c from OpportunityLineItem where OpportunityId in :scope]) {
opportunityLineItemMap.put(oli.Id,oli);
}
List<OpportunityLineItem> removeOpportunityLineItemList = new List<OpportunityLineItem>();
List<Opportunity> newScope = new List<Opportunity>();
List<Opportunity> alteredScope = new List<Opportunity>();
for(Opportunity o: scope) {
if(o.StageName=='1 - Lead' && opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)) {
removeOpportunityLineItemList.add(opportunityLineItemMap.remove(o.Ser_Line_Item_ID__c));
o.Ser_Line_Item_ID__c = null;
o.CurrencyIsoCode=o.Ser_Currency_Code__c;
alteredScope.add(o);
} else if(o.StageName!='1 - Lead' && o.CurrencyIsoCode!=o.Ser_Currency_Code__c) {
if(opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)) {
removeOpportunityLineItemList.add(opportunityLineItemMap.remove(o.Ser_Line_Item_ID__c));
o.Ser_Line_Item_ID__c = null;
}
o.CurrencyIsoCode=o.Ser_Currency_Code__c;
alteredScope.add(o);
newScope.add(o);
} else if(o.StageName!='1 - Lead' && opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)){
newScope.add(o);
} else if(o.StageName!='1 - Lead' && !opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)){
o.CurrencyIsoCode=o.Ser_Currency_Code__c;
newScope.add(o);
}
}
// Delete those marked as invalid
delete removeOpportunityLineItemList;
// Remove old reference after we delete
update alteredScope;
// Opportunity map.
Map<Id,Opportunity> ServiceOpportunityMap = new Map<Id,Opportunity>(newScope);
List<OpportunityLineItem> upsertOpportunityLineItemID = new List<OpportunityLineItem>();
// Populate ServicePriceBookEntryMap with map of ISO code to ID
Map<String,PricebookEntry> ServicePriceBookEntryMap = new Map<String,PricebookEntry>();
for(PricebookEntry pbe : [select id, CurrencyisoCode from PricebookEntry where ProductCode = 'Ser']) {
if(!ServicePriceBookEntryMap.containsKey(pbe.CurrencyIsoCode)) {
ServicePriceBookEntryMap.put(pbe.CurrencyisoCode,pbe);
}
}
for(Opportunity o: newScope) {
Id pricebookEntryId = null;
if(ServicePriceBookEntryMap.containsKey(o.Ser_Currency_Code__c)) {
pricebookEntryId = ServicePriceBookEntryMap.get(o.Ser_Currency_Code__c).Id;
}
OpportunityLineItem oli;
// get old lineitem
if(opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)) {
oli = opportunityLineItemMap.get(o.Ser_Line_Item_ID__c);
}
// if none found create new one and setup defaults
if(oli==null) {
oli = new OpportunityLineItem();
oli.OpportunityId = o.Id;
oli.PricebookEntryId = pricebookEntryId;
oli.Seats__c = 0;
oli.Wave__c = '1';
oli.X2023_Revenue__c = 0;
oli.X2022_Revenue__c = 0;
oli.Delivery_LoSerion__c = 'Other';
oli.FTE__c = 0;
oli.Language__c = 'English';
}
// New or Update copy these fields
oli.Quantity = Math.max(1,o.Ser_Duration__c);
oli.ServiceDate = o.Ser_Start_Date__c;
oli.UnitPrice = o.Ser_Monthly_Amount__c;
upsertOpportunityLineItemID.add(oli);
}
if(!upsertOpportunityLineItemID.isEmpty()) {
upsert upsertOpportunityLineItemID;
for(OpportunityLineItem oli : upsertOpportunityLineItemID) {
Opportunity o = ServiceOpportunityMap.get(oli.OpportunityId);
o.Ser_Line_Item_ID__c = oli.Id;
o.SER_Updated__c = false;
}
update newScope;
}
}
public void finish(Database.BatchableContext BC){
if(BC.getJobId()==lastJobId) {
lastJobId=null;
}
}
private Map<String,RecordType> opportunityRTMap = getRecordTypeMap('Opportunity');
private List<RecordType> getRecordTypes(String[] objects) {
return [SELECT Id, name, SObjectType FROM RecordType WHERE SObjectType in :objects order by SobjectType, Name];
}
private Map<String,RecordType> getRecordTypeMap(String objectName) {
Map<String,RecordType> target = new Map<String,RecordType>();
for(RecordType r : getRecordTypes(new String[] {objectName})) {
target.put(r.name,r);
}
return target;
}
private Map<String,RecordType> getRecordTypeMap(String[] objects) {
Map<String,RecordType> target = new Map<String,RecordType>();
for(RecordType r : getRecordTypes(objects)) {
target.put(r.SObjectType+'.'+r.name,r);
}
return target;
}
public static ID execute() {
try {
return System.scheduleBatch(new ServiceBatchable(),'ServiceBatchable',1,200);
} Catch (Exception ex) {
// We don't care that another is setup
System.debug(ex);
}
return null;
}
}
Here is the batch class, how to write test coverage for batch class
public class ServiceBatchable implements Database.Batchable<sObject>, Database.Stateful {
private Id lastJobId = null;
private Id serRecTypeId = null;
public ServiceBatchable () {
}
public Database.QueryLoSeror start(Database.BatchableContext BC) {
Integer limitInt = 10000;
List<AsyncApexJob> aajList = new List<AsyncApexJob>();
if(lastJobId!=null && lastJobId!=BC.getJobId()) {
aajList.addAll([SELECT Id, Status, CompletedDate FROM AsyncApexJob WHERE ID =: lastJobId and JobType!='BatchApexWorker' and Status not in ('Aborted','Completed','Failed')]);
}
if(lastJobId==null || aajList.isEmpty()) {
lastJobId = BC.getJobId();
if(serRecTypeId ==null) {
RecordType rt = opportunityRTMap.get('Service Record');
if(rt!=null) {
serRecTypeId = rt.Id;
}
}
}
if(lastJobId!=BC.getJobId()) {
limitInt = 0;
System.debug('ServiceBatchable: Previous Job alive still - aborting '+BC.getJobId());
}
return Database.getQueryLocator([
select id,CurrencyIsoCode,StageName,Ser_Currency_Code__c,Ser_Line_Item_ID__c,Ser_Duration__c,Ser_Start_Date__c,Ser_Monthly_Amount__c,SER_Updated__c
from Opportunity where
((StageName='1 - Lead' and Ser_Line_Item_ID__c != null) or (StageName!='1 - Lead')) and
SER_Updated__c = true and
External_Id__c != null and
RecordTypeId=: serRecTypeId and
isDeleted=FALSE
limit :limitInt
]);
}
public void execute(Database.BatchableContext BC, List<Opportunity> scope){
Map<Id,OpportunityLineItem> opportunityLineItemMap = new Map<Id,OpportunityLineItem>();
for(OpportunityLineItem oli : [select id,OpportunityId,X2022_Revenue__c,X2023_Revenue__c,Wave__c,UnitPrice,ServiceDate,Seats__c,Quantity,PricebookEntryId,Language__c,FTE__c,Delivery_LoSerion__c from OpportunityLineItem where OpportunityId in :scope]) {
opportunityLineItemMap.put(oli.Id,oli);
}
List<OpportunityLineItem> removeOpportunityLineItemList = new List<OpportunityLineItem>();
List<Opportunity> newScope = new List<Opportunity>();
List<Opportunity> alteredScope = new List<Opportunity>();
for(Opportunity o: scope) {
if(o.StageName=='1 - Lead' && opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)) {
removeOpportunityLineItemList.add(opportunityLineItemMap.remove(o.Ser_Line_Item_ID__c));
o.Ser_Line_Item_ID__c = null;
o.CurrencyIsoCode=o.Ser_Currency_Code__c;
alteredScope.add(o);
} else if(o.StageName!='1 - Lead' && o.CurrencyIsoCode!=o.Ser_Currency_Code__c) {
if(opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)) {
removeOpportunityLineItemList.add(opportunityLineItemMap.remove(o.Ser_Line_Item_ID__c));
o.Ser_Line_Item_ID__c = null;
}
o.CurrencyIsoCode=o.Ser_Currency_Code__c;
alteredScope.add(o);
newScope.add(o);
} else if(o.StageName!='1 - Lead' && opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)){
newScope.add(o);
} else if(o.StageName!='1 - Lead' && !opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)){
o.CurrencyIsoCode=o.Ser_Currency_Code__c;
newScope.add(o);
}
}
// Delete those marked as invalid
delete removeOpportunityLineItemList;
// Remove old reference after we delete
update alteredScope;
// Opportunity map.
Map<Id,Opportunity> ServiceOpportunityMap = new Map<Id,Opportunity>(newScope);
List<OpportunityLineItem> upsertOpportunityLineItemID = new List<OpportunityLineItem>();
// Populate ServicePriceBookEntryMap with map of ISO code to ID
Map<String,PricebookEntry> ServicePriceBookEntryMap = new Map<String,PricebookEntry>();
for(PricebookEntry pbe : [select id, CurrencyisoCode from PricebookEntry where ProductCode = 'Ser']) {
if(!ServicePriceBookEntryMap.containsKey(pbe.CurrencyIsoCode)) {
ServicePriceBookEntryMap.put(pbe.CurrencyisoCode,pbe);
}
}
for(Opportunity o: newScope) {
Id pricebookEntryId = null;
if(ServicePriceBookEntryMap.containsKey(o.Ser_Currency_Code__c)) {
pricebookEntryId = ServicePriceBookEntryMap.get(o.Ser_Currency_Code__c).Id;
}
OpportunityLineItem oli;
// get old lineitem
if(opportunityLineItemMap.containsKey(o.Ser_Line_Item_ID__c)) {
oli = opportunityLineItemMap.get(o.Ser_Line_Item_ID__c);
}
// if none found create new one and setup defaults
if(oli==null) {
oli = new OpportunityLineItem();
oli.OpportunityId = o.Id;
oli.PricebookEntryId = pricebookEntryId;
oli.Seats__c = 0;
oli.Wave__c = '1';
oli.X2023_Revenue__c = 0;
oli.X2022_Revenue__c = 0;
oli.Delivery_LoSerion__c = 'Other';
oli.FTE__c = 0;
oli.Language__c = 'English';
}
// New or Update copy these fields
oli.Quantity = Math.max(1,o.Ser_Duration__c);
oli.ServiceDate = o.Ser_Start_Date__c;
oli.UnitPrice = o.Ser_Monthly_Amount__c;
upsertOpportunityLineItemID.add(oli);
}
if(!upsertOpportunityLineItemID.isEmpty()) {
upsert upsertOpportunityLineItemID;
for(OpportunityLineItem oli : upsertOpportunityLineItemID) {
Opportunity o = ServiceOpportunityMap.get(oli.OpportunityId);
o.Ser_Line_Item_ID__c = oli.Id;
o.SER_Updated__c = false;
}
update newScope;
}
}
public void finish(Database.BatchableContext BC){
if(BC.getJobId()==lastJobId) {
lastJobId=null;
}
}
private Map<String,RecordType> opportunityRTMap = getRecordTypeMap('Opportunity');
private List<RecordType> getRecordTypes(String[] objects) {
return [SELECT Id, name, SObjectType FROM RecordType WHERE SObjectType in :objects order by SobjectType, Name];
}
private Map<String,RecordType> getRecordTypeMap(String objectName) {
Map<String,RecordType> target = new Map<String,RecordType>();
for(RecordType r : getRecordTypes(new String[] {objectName})) {
target.put(r.name,r);
}
return target;
}
private Map<String,RecordType> getRecordTypeMap(String[] objects) {
Map<String,RecordType> target = new Map<String,RecordType>();
for(RecordType r : getRecordTypes(objects)) {
target.put(r.SObjectType+'.'+r.name,r);
}
return target;
}
public static ID execute() {
try {
return System.scheduleBatch(new ServiceBatchable(),'ServiceBatchable',1,200);
} Catch (Exception ex) {
// We don't care that another is setup
System.debug(ex);
}
return null;
}
}
Refer the below links will help you to proceed further on your test class.
https://jayakrishnasfdc.wordpress.com/2021/01/02/apex-test-class-for-batch-apex/
https://acesalesforce.com/test-class-batch-class/
Thanks!!
Try Below Code Please Mark It As Best Answer If It Helps
Thank You!
below is the error while executing test methos
System.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, You may not Change an opportunity owned by the Salesforce system..: []
System.LimitException: Too many SOQL queries: 101