I have created below batch apex class. I have also created test class for this. But this test class is only covering 27% of batch apex class. Also, it is not calling execute method of batch apex class.

Batch Apex class:

global class LeadDuplicateRemove implements Database.Batchable < sObject > {

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('select Id, CreatedDate, Phone, Status, Email from Lead Where convertedbusiness__c != null and LeadAudit__c = null  and isDeleted = false order by CreatedDate ASC Limit 1');

    global void execute(Database.BatchableContext bc, List < Lead > scope) {
        for (Lead lead: scope) {
            Database.QueryLocator leadQueryLocator = Database.getQueryLocator([Select Id, CreatedDate, Phone, Status, Email from Lead where convertedbusiness__c != null and LeadAudit__c = '1' and isDeleted = false order by CreatedDate ASC Limit 1]);

            Database.QueryLocatorIterator iterator = leadQueryLocator.iterator();
            while (iterator.hasNext()) {
                Lead leadObj = (Lead) iterator.next();

                if(lead.ConvertedBusiness__c == leadObj.ConvertedBusiness__c){
                    lead.ConvertedBusiness__c = null;
    global void finish(Database.BatchableContext bc) {

Test class:

@isTest global class LeadDuplicateRemoveTest {
    global static void setup() {

        Lead lead1 = new Lead(LastName='testlead1 ', RAF_Nurture_Campaign__c = 'None',
                              company='test', Email='[email protected]',Phone = '1111111111',Status ='Completed');

        insert lead1;
        insert new Lead(LastName='testlead1', RAF_Nurture_Campaign__c = 'None',
                               company='Vtest', Email='[email protected]',Phone = '222222',Status ='Open');

    @isTest global static void TestRun() {         
        Database.executeBatch(new LeadDuplicateRemove());



enter image description here


1 Answer 1


You have the filter convertedbusiness__c != null but when you are creating the lead, you are not setting this.

Lead lead1 = new Lead(convertedbusiness__c= ??, LastName='testlead1 ', RAF_Nurture_Campaign__c = 'None',
                          company='test', Email='[email protected]',Phone = '1111111111',Status ='Completed');

As no records are returned from start method, it is not even invoking execute method


Also, you have query locator and iterator inside execute - which is not needed. You are returning leads where LeadAudit__c = null and again processing on records where LeadAudit__c = '1'. You might as well remove the filter LeadAudit__c = null from start method and process the records inside execute without iterator.

  • 2
    Also, there's no DML operation, so changes won't be persisted in execute method.
    – sfdcfox
    Commented Aug 17, 2019 at 8:07
  • +1. Reason database query iterator inside execute method is I am comparing leads records leadautit__c = null received in start methods to lead records with leadaudit__c = '1'. Isn't this right way to do ?
    – DRules
    Commented Aug 17, 2019 at 17:43
  • You can get the records without lead audit filter. Inside execute method scope you get both types of records which you can compare. No need of any query again Commented Aug 17, 2019 at 17:52
  • But the thing is I want to compare only those leadaudit = null records to leadaudit = 1. if i keep leadaudit = null in start than it will will only fetch those leads in scope. So that I can compare each of that record with leadauit =1 record in execute method. Am i doing anything wrong here ?
    – DRules
    Commented Aug 17, 2019 at 19:17

Not the answer you're looking for? Browse other questions tagged .