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
cooldamselcooldamsel 

[Urgent!!!] Test Coverage for Batch Apex Class

Hi,

I am a newbie in salesforce. I have a batch apex class. I wrote a test class for the class and my test method is passed but am not getting the code coverage. I have covered 42% of the code.

Apex Class:
global class EF_OKTA_Queue_Batch implements Database.Batchable <sObject>, Database.AllowsCallouts
{
    private String query;
    private list<EF_OKTA_Queue__c> lstoktaQueueUpdate = new list<EF_OKTA_Queue__c>();

    global EF_OKTA_Queue_Batch ()
    {
         query =    EF_SOQL_Statements__c.getValues('EF_OKTA_Queue_Batch_Query').Type__c + ' ' + EF_SOQL_Statements__c.getValues('EF_OKTA_Queue_Batch_Query').Fields__c +
                    EF_SOQL_Statements__c.getValues('EF_OKTA_Queue_Batch_Query').Relationship_fields__c + ' from ' +  EF_SOQL_Statements__c.getValues('EF_OKTA_Queue_Batch_Query').Object__c +
                    ' where ' + EF_SOQL_Statements__c.getValues('EF_OKTA_Queue_Batch_Query').Filter__c;
         
    }


    global Database.QueryLocator start(Database.BatchableContext bc)
    {
        return Database.getQueryLocator(query);
    }


    global void execute(Database.BatchableContext BC, List <EF_OKTA_Queue__c> scope)
    {
        List<String> queueWithEmptyURL       = new List<String>();
        List<EF_OKTA_Queue__c> itemsToUpdate = new List<EF_OKTA_Queue__c>();
        Map<String, String> errorsToLog      = new Map<String, String>();
        EF_OKTA_RESTAPI objEFAPI             = null;

        for (EF_OKTA_Queue__c oktaQueue: scope) {
            if (oktaQueue.OKTA_URL__c == null || oktaQueue.OKTA_URL__c.trim() == '') {
                queueWithEmptyURL.add(oktaQueue.id);
                continue;
            }
            // After 15 minutes (Scheduled Job) mark status to complete
            if (oktaQueue.EF_Requested_Resource__r.EF_Resource_Metadata__r.Type__c == 'HYBRID AUTOMATED' && oktaQueue.CreatedDate.addMinutes(15) < Datetime.now()) {
                // additional logic in trigger
                oktaQueue.Status__c = 'Complete';
            } else if (oktaQueue.EF_Requested_Resource__r.EF_Resource_Metadata__r.Type__c == 'HYBRID' && oktaQueue.CreatedDate.addMinutes(15) < Datetime.now()) {
                // additional logic in trigger
                oktaQueue.Status__c = 'Complete';
            } else if (oktaQueue.EF_Requested_Resource__r.EF_Resource_Metadata__r.Type__c == 'AUTOMATED') {
                // API Class object
                objEFAPI = new EF_OKTA_RESTAPI();
                // disable error log to avoid problems with executing a call, storing error record and getting an exception when trying to execute second call
                objEFAPI.setDisableErrorLog(true);
                // Execute call and query for current user data / profile
                String currentJSON = objEFAPI.getOKTAAttributes(oktaQueue.OKTA_URL__c);
                // extract Synchronisation Status
                String status = EF_OKTA_Queue_Batch.getSyncState(currentJSON);

                if (status == 'SYNCHRONIZED') {
                    // sync status is ok so let's mark queue item as complete
                    oktaQueue.Status__c = 'Complete';
                } else {
                    // not synced yet, let's try some other time ...
                    oktaQueue.number_tried__c += 1;

                    // there might be an error so let's log it
                    if ('' == status) {
                        errorsToLog.put(oktaQueue.id, currentJSON);
                    }
                }
            }

            itemsToUpdate.add(oktaQueue);
        }

        try {
            // process queueWithEmptyURL first (cannot do it future)
            EF_OKTA_Queue obj = new EF_OKTA_Queue();
            obj.execute(queueWithEmptyURL);

            // update items that already have url
            if (itemsToUpdate.isEmpty() == false) {
                update itemsToUpdate;
            }
        } catch(Exception ex) {
            string strError = '';
            for (EF_OKTA_Queue__c oktaQueue: scope) {
                strError = (strError!='') ? (strError +  ',' + oktaQueue.id) : oktaQueue.id;
            }
            EF_Error_Log.logException('EF_OKTA_Queue_Batch', strError, 'DML', 'HIGH', ex.getMessage() +  '\n\nStack Trace:\n' + ex.getStackTraceString());
        }

        // if there were some invalid responses log them as errors into the log object
        if (errorsToLog.isEmpty() == false) {
            String message = '';
            for (String queueId : errorsToLog.keySet()) {
                message = errorsToLog.get(queueId);
                if (message == '') {
                    message = 'JSON Response was empty ...';
                }
                EF_Error_Log.logException('EF_OKTA_Queue_Batch', queueId, 'OKTA', 'HIGH', message);
            }
        }
    }

    global void finish(Database.BatchableContext BC)
    {
        //Final Actions: requirements not defined yet will update the code
    }

    global static string getSyncState(string jsonString)
    {
        string status = '';
        if (jsonString == null || jsonString.trim() == '') {
            return status;
        }

        try {
            Map<String, Object> tmp = (Map<String, Object>) JSON.deserializeUntyped(jsonString);

            if (false == tmp.containsKey('syncState')) {
                return status;
            }

            status = (String) tmp.get('syncState');
        } catch (Exception e) {
            // we don't care about the error here, it just means that status is not
            // synchronised and we need to repeat the query/request
            // json response will be logged by the calling method above
        }

        return status;
    }
}

Test Class:

@isTest
private class EF_OKTA_Queue_Batch_Test
{
   
    static TestMethod void OKTAQueueBatchTest()
    {   
         Database.QueryLocator QueryLoc;
         Database.BatchableContext BatchCont;
         List<EF_OKTA_Queue__c> lstOKTAQ= new List<EF_OKTA_Queue__c>();
        
         EF_SOQL_Statements__c objStmts= EF_DataFactory_Utility.insert_EF_SOQL_Statements();
       
         EF_OKTA_Queue_Batch ObjOKTAQbatch = new EF_OKTA_Queue_Batch();
        
         ID batchprocessid = Database.executeBatch(ObjOKTAQbatch,200);
         System.debug('######EXECUTE BATCH'+ batchprocessid);        
                 
         List<EF_OKTA_Queue__c> lstOKTAQueue = new List<EF_OKTA_Queue__c>();
        
         lstOKTAQueue = EF_DataFactory_Utility.insert_EF_OKTA_Queue();        
         insert lstOKTAQueue;
        
         QueryLoc= ObjOKTAQbatch.start(BatchCont);
        
         System.debug(BatchCont);
        
         Database.QueryLocatorIterator QueryIterate = QueryLoc.iterator();
         while (QueryIterate.hasNext())
         {
             EF_OKTA_Queue__c objQueue = (EF_OKTA_Queue__c)QueryIterate.next();           
             System.debug(objQueue);
             System.debug(objQueue.OKTA_URL__c);
             lstOKTAQ.add(objQueue);
         }       
        
         ObjOKTAQbatch.execute(BatchCont, lstOKTAQ);
         ObjOKTAQbatch.finish(BatchCont); 
        
         String json = '{'+
            '    \"items\": ['+
            '        {'+
            '            \"id\": \"pn0\",'+
            '            \"syncState\": \"0\",'+
            '            \"managerID\": \"pc0\"'+
            '        },'+
            '        {'+
            '            \"id\": \"pn1\",'+
            '            \"syncState\": \"1\",'+
            '            \"managerID\": \"pc1\"'+
            '        },'+
            '        {'+
            '            \"id\": \"pn2\",'+
            '            \"syncState\": \"2\",'+
            '            \"managerID\": \"pc2\"'+
            '        }'+
            '    ]'+
            '}';
           
        EF_OKTA_Queue_Batch.getSyncState(json);      
      
    }
}

Please help me out.

Thanks in Advance!!!
NehalNehal (Salesforce Developers) 
Hi,

The links below will help you with the details on how to increase the code coverage of batch apex class:

1.http://salesforceonlinetrainings.blogspot.com/2012/08/adding-test-for-batch-apex-class.html
2.http://stackoverflow.com/questions/17676835/how-to-write-a-test-class-for-batch-apex-class
3.http://salesforce.stackexchange.com/questions/22420/code-coverage-for-batch-apex
4.https://developer.salesforce.com/forums/ForumsMain?id=906F000000098YQIAY

I hope this helps.