0

I have a Batch class, which queries Lead records that were created 1 day before. I have created a custom Label 'More_Than_1_days' which has the value 1. I was using this custom label in that batch class to dynamically fetch Leads that were created on particular number of days before as mentioned in the code.The reason I'm going with Custom label is because ,later if needed I can modify the label value to something.

I'm scheduling this batch class to run at a particular time using another Apex class which has a Schedulable interface.

This is the batch class

public class Lead_Batch_scheduler implements Database.Batchable<sObject>
{
    Public Database.QueryLocator start(Database.BatchableContext bc)
    {
        Integer days_old = Integer.valueof(label.More_than_1_days);
        return Database.getQueryLocator([
                                    SELECT Id, OwnerId, CreatedDate
                                    FROM Lead
                                    WHERE Status = 'New'
                                    AND CreatedDate >=: (system.today() - days_old)
                                     ]);       
    }
   Public void execute(Database.BatchableContext bc, List<Lead> LL)
   {
        List<Task> tasks = new List<Task>();
        try{
        for (Lead leadRecord : LL) {
                                    Task NT = new Task();
                                    NT.Subject = 'Lead-to-Task';
                                    NT.ActivityDate = Date.today();
                                    NT.OwnerId = leadRecord.OwnerId;
                                    NT.WhoId = leadRecord.Id;
                                    NT.Description = 'This lead needs attention';          
                                    tasks.add(NT);
                                    }
        if (!tasks.isEmpty())
        {
            insert tasks;
        }
       }
        catch(Exception e)
        {
        System.debug('Error Caught in Execute Method '+ e.getmessage());
        }
    }
   Public void finish(Database.BatchableContext bc) {
       system.debug('completed');
    }
}

This is my Scheduler Class.

public class SchedulerforLeadBatch implements Schedulable {

public static void execute(SchedulableContext sc){
Lead_Batch_scheduler lb = new Lead_Batch_scheduler();
Database.executeBatch(lb,10);
}

}

This is my Test class

@isTest
public class SchedulerLeadBatch_Test {
 @isTest 
    Static void testSchedule(){
        Test.StartTest();
      SchedulerforLeadBatch Batch_Task = New SchedulerforLeadBatch();
        String Cron = '0 05 19 * * ?';
        system.schedule('ScheduleBatch', Cron, Batch_Task );
        Test.stopTest();
    }
}

While running the test class my batch class is not getting covered only 26%. The whole execute method of my batch class is not covered. May I know where the mistake is?

Or else do I need to write a test class separately for batch class unlike I'm calling the scheduler class inside my test class which in turn calls the batch class.

2
  • Are you creating test data?
    – Girbot
    Feb 20 at 13:01
  • No, I haven't created test data. Will create and see whether my test class is checking the execute method of the batch class. Thanks @Girbot
    – Mohd hasim
    Feb 20 at 13:48

2 Answers 2

0

You need to create data for your test. By default, tests are kept isolated from the actual data in your org (and this is a good thing) except for a handful of objects like User, Profile, Role, and some others (collectively known as "setup objects").

Since you're not inserting any leads in your test, the start method is returning nothing for the query locator. So there is no work to do and the execute() method is not run.

Another thing to note is that you can (and probably should) be calling the start(), execute() and finish() methods of your batch class directly. Outside of getting some coverage for your schedulable class, you're not really interested in testing that Salesforce calls the right batch class (that's Salesforce's responsibility to test, and we should trust that their features work).

In 99% of cases, it's completely fine to pass null in for the BatchableContext (and also things like SchedulableContext and QueueableContext)

2
  • Ok got that. I have to create test data for querying the lead records,as test class doesn't do the check on Salesforce existing records.
    – Mohd hasim
    Feb 20 at 13:51
  • Thanks.I have updated the answer. Check and ensure its correctness and efficiency.
    – Mohd hasim
    Feb 20 at 19:35
0

I got it. Thanks @Girbot and @Derek F.

Created test data for test class and now the test class is covering 94%. I'm left with only the exception line.

Below is my updated test class and test data for the batch class.

This is the test data Apex class.

@isTest
public class TestDataForLeadBatch {

    public static List<Lead> leadforbatch(){
        List<Lead> leadsList = new List<Lead>();
        for (Integer i = 0; i < 5; i++) {
            Lead lead = new Lead();
            lead.Status = 'Open - Not Contacted';
            lead.LastName = 'xyz';
            lead.Company = 'citta';
         
            leadsList.add(lead);
        }
        insert leadsList;
        
        List<Task> tasks = new List<Task>();
        
        for (Lead lead_var : leadsList) {
                                    Task NT = new Task();
                                    NT.Subject = 'Lead-to-Task';
                                    NT.ActivityDate = Date.today();
                                    //NT.OwnerId = lead_var.OwnerId;
                                    NT.WhoId = lead_var.Id;
                                    NT.Description = 'This lead needs attention';          
                                    tasks.add(NT);
                                    }
        if (!tasks.isEmpty())
        {
            insert tasks;
        }
        
        return leadsList;
    }
}

This is the updated test class.

@isTest
private class LeadBatchTestClass {
  static testMethod void testBatchClass() {
      
      Lead[] leadslist = TestDataForLeadBatch.leadforbatch(); 
       
        Test.startTest();
      String cronExp = '0 50 00 * * ?';
        System.schedule('Lead Batch Scheduling',cronExp, new SchedulerforLeadBatch());
        Test.stopTest();
      
        List<Task> tasks = [SELECT Id FROM Task WHERE Subject = 'Lead-to-Task'];
        System.assertEquals(5, tasks.size());
    }
}
1
  • N.B. if (!tasks.isEmpty()) can be skipped; doing DML on empty lists does not burn any limits
    – cropredy
    Feb 22 at 2:12

You must log in to answer this question.

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