+ Start a Discussion
Arpitha GowdaArpitha Gowda 

Test class for batch apex approval process

Hello all

I have Designed a batch apex where it gets automatically approved after 24Hrs if no actions are taken, and i have 
written test class which is getting covered only 15%, how do increase the code coverage, Please help
 
global class BatchOpportunityApproval implements Database.Batchable<sObject>, Schedulable, Database.Stateful {
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        String Query = 'SELECT Id,DaysSinceApprovalNotDone__c,Approval_Sent_Date_Time__c FROM Opportunity where DaysSinceApprovalNotDone__c = 1 AND Approval_Sent_Date_Time__c !=null';
        return Database.getQueryLocator(Query);
    }
    global void execute(Database.BatchableContext BC, List<Opportunity> scope){

        List<Opportunity> opplist = new List<Opportunity>();
        Set<Id> OppIds = New Set<Id>();
        for(Opportunity opp : scope){    
            opp.Approval_Sent_Date_Time__c = null;
            opplist.add(opp);
            OppIds.add(opp.id);
        }
        
        Set<Id> pIds = (new Map<Id, ProcessInstance>([SELECT Id,Status,TargetObjectId FROM ProcessInstance where Status='Pending' and TargetObjectId IN :OppIds])).keySet();
        Set<Id> pwi = (new Map<Id, ProcessInstanceWorkitem>([SELECT Id,ProcessInstanceId FROM ProcessInstanceWorkitem WHERE ProcessInstanceId IN :pIds])).keySet();
        List<Approval.ProcessWorkitemRequest> allReq = new List<Approval.ProcessWorkitemRequest>(); 
        if(!pwi.IsEmpty()){
            for (Id pInstanceWorkitemsId:pwi){
                system.debug(pInstanceWorkitemsId);
                Approval.ProcessWorkitemRequest req = new Approval.ProcessWorkitemRequest();
                req.setComments('24hrs Auto Approval for Pending Opportunities');
                req.setAction('Approve');
                req.setWorkitemId(pInstanceWorkitemsId);
                system.debug(pInstanceWorkitemsId);
                allReq.add(req);
            }
        }
        
        if(allReq.size()>0){
            Approval.ProcessResult[] result2 =  Approval.process(allReq);
        }     
        
        if(opplist.size()>0){
            Database.update(opplist,false);
        }
    }
    
    global void finish(Database.BatchableContext BC) {}
    
    global void execute(SchedulableContext sc) {}
}

My test class covering only 15%
 
@isTest
public class BatchOpportunityApprovalTestclass {
    static testMethod void mytestmethod(){
        Test.startTest();
        Account ac = new Account(Name='TestAccount', Website='www.salesforce.com');
        insert ac;
        
        List<Opportunity> opps = new List<Opportunity>();
        for(Integer k=0; k<50; k++){
            opps.add(new Opportunity(Name=ac.Name + ' Opportunity ' + k,
                                     StageName='Stage 0 (0%)',
                                     CloseDate=System.today(),
                                     Practices__c = 'Cloud',
                                     Status__c = 'Active',
                                     No_of_Engineers__c = 20,
                                     Competition_Fulfilment_LOSS__c = 20,
                                     Priority__c = '1 - Lowest',
                                     Sales_Action_Items_Remarks__c = 'Hello',
                                     Category__c = 'Critical',
                                     Fulfilled_as_on_date_WIN__c = 20,
                                     Customer_Kept_On_Hold_Fulfilled__c = 20,
                                     Duration_Months__c = 10,
                                     Business_Model__c = 'T&M',
                                     Customer_Location__c = 'Bangalore',
                                     Revenue_Type__c = 'EE-Existing Customer Existing Business',
                                     Experience_Range__c = 'Min Exp',
                                     Skill_Category__c = 'Development',
                                     EnggStatusType__c = 'self',
                                     RMG_Remarks__c = 'HelloWorld',
                                     //Approval_Sent_Date_Time__c = system.now()-1,                                     
                                     AccountId=ac.Id));
        }
        insert opps;
        
        Approval.ProcessSubmitRequest [] requestList = new Approval.ProcessSubmitRequest []{};
        for(Opportunity op: [SELECT Id, Name,DaysSinceApprovalNotDone__c, Approval_Sent_Date_Time__c FROM Opportunity WHERE Id IN: opps]){
            System.debug('op>>>>'+op.Approval_Sent_Date_Time__c);
            System.debug('op>>>><<<<'+op.DaysSinceApprovalNotDone__c);
            Approval.ProcessSubmitRequest req = new Approval.ProcessSubmitRequest();          
            req.setComments('Submitting approval request');        
            req.setObjectId(op.id);
            req.setProcessDefinitionNameOrId('Opportunity Approval Process');
            requestList.add(req);
           
        }
        if(requestList.size()>0){
            Approval.ProcessResult[] result = Approval.process(requestList);
        }
            
        SchedularForBatchOpportunityApproval testsche = new SchedularForBatchOpportunityApproval();
        String sch = '0 0 1 * * ?';
        system.schedule('Test status Check', sch, testsche );
        
        Test.stopTest();
    }
    
     public static testMethod void testschedule() {
        Test.StartTest();
        SchedularForBatchOpportunityApproval sh1 = new SchedularForBatchOpportunityApproval();
        String sch = '0 00 01 * * ?'; 
        //ID batchprocessid = Database.executeBatch(sh1);
        String jobId = system.schedule('SchedularForBatchOpportunityApproval', sch, sh1);
        System.assert(jobId != null);
        Test.stopTest(); 
    }
}

​​​​​​​
Andrew GAndrew G
My brain is tired, but at a guess does it have something to do with the code doing a select where DaysSinceApprovalNotDone__c =1 is part of the selection/query criteria and I don't see that field (DaysSinceApprovalNotDone__c ) being set in the test data?

Set the value of that field to be 1 in your test data setup and then try.
If it's some computed field, for exmaple some measure of time since the record was created, have a look at 
Test.setCreatedDate(recordId,dateTime);
Example: 
Datetime yesterday = Datetime.now().addDays(-1);
for(Opportunity op: [SELECT Id FROM Opportunity WHERE Id IN: opps]){ 
    Test.setCreatedDate(op.Id,yesterday );
 }



Regards
Andrew
 
Talikota SaikamalTalikota Saikamal
Hi Arpitha,
this is my Code Which could help You 


 
@istest 
public class Test_BatchClassForApproval { 
private static testmethod void ApprovalBatch(){ 
  Opportunity Opp=new Opportunity(); 
   Opp.Name='TestOpp'; 
   Opp.CloseDate= Date.newInstance(2016, 12, 9) ; 
   Opp.StageName='Closed Won'; 
   Opp.Region__c='North-INDIA';
    Insert Opp; 
Approval.ProcessSubmitRequest appReq=new Approval.ProcessSubmitRequest(); appReq.setObjectId(Opp.id);
   Approval.ProcessResult AppResult =Approval.process(appReq);
       test.startTest();
      BatchClassForApproval bc=new BatchClassForApproval(); 
      database.executeBatch(bc); 
       test.stopTest(); 
     }
}