1

I've been staring at this for far too long so would VERY MUCH appreciate help on what's going on here! This should be a relatively straightforward Batch Apex from the Asychronous Apex trail. 

When I run the test, it runs the start and finish methods and skips execute entirely. 

Test class:

@isTest
public class LeadProcessorTest {

    @isTest
    public static void testLeadProcessor() {
     
        List<Lead> listOfLeads = new List<Lead>();
        
        for(Integer i = 0; i < 200; i++) {
            Lead l = new Lead();
            l.LastName = 'Testing' + i;
            l.Company = 'Test Company ABC';
            l.Status = 'Open - Not Contacted';
            l.LeadSource = 'Web';
            listOfLeads.add(l);
        }
        
        System.debug('Number of leads created ' + listOfLeads.size());
        insert listOfLeads;
    }
    
    @isTest static void test() {
        Test.startTest();
        LeadProcessor lp = new LeadProcessor();
        Id batchId = Database.executeBatch(lp);
        Test.stopTest();
    }

}

Lead Processor class:

global class LeadProcessor implements Database.Batchable<sObject> {
    Integer recordsProcessed = 0;
    
    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT Id, LeadSource FROM Lead');
    }
    
    public void execute(Database.BatchableContext bc, List<Lead> leads){
        List<Lead> myLeads = new List<Lead>();
        for(Lead currl : leads) {
            currl.LeadSource = 'Dreamforce';
            myLeads.add(currl);
            recordsProcessed += 1; 
        }
        
        update myLeads;
    }
    
    public void finish(Database.BatchableContext bc) {
        System.debug('Number of records processed: ' + recordsProcessed);
    }
}

1 Answer 1

5

testLeadProcessor() and test() are separate unit tests, which execute in separate, isolated test data contexts. The Leads inserted will not be visible to test() because they're inserted in a distinct context.

Then, execute() is not being executed because the query in start() returns no records.

The fix is easy: annotate testLeadProcessor() with the Apex annotation that corresponds to its actual role in this test suite, @testSetup, instead of @isTest. That will result in it executing before each unit test in this class, and the data it creates will be visible to the code executed in those tests.

3
  • Thanks David! That worked, and I learned about @testSetup :)
    – sbm7x5
    Mar 26, 2021 at 20:53
  • Strictly it executes once and the database state after its execution is shared by each test method in the same test class.
    – Phil W
    Mar 27, 2021 at 8:26
  • Do we need to call the "testsetup" method in the "isTest" method? Aug 5, 2022 at 12:19

You must log in to answer this question.

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