1

I have written the following batch apex class and corresponding test class. Tests are successful but the execute method is never called. I have attempted to debug to try to pinpoint the problem but have had no luck.

Batch Class

global class BatchAddToCampaign implements Database.Batchable<sObject>,  Database.Stateful
{
    global final Id campaignId;
    global final Set<Id> qKeys;

    global BatchAddToCampaign(Id campaignId, Set<Id> qKeys){
        this.campaignId = campaignId;
        this.qKeys = qKeys;
    System.Debug('this.campaignId is ' + campaignId);         
    System.Debug('this.qkeys is ' + qKeys);                 

    }

    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator('Select Id From Lead Where Id In :qKeys');
    }

    global void execute(Database.BatchableContext BC, List<Lead> scope) {
        System.Debug('Starting Execute Method!');         
        Integer collsize; 
        List<CampaignMember> cm = new List<CampaignMember>();   
        Map<Id, Campaign> cmMap = new Map<Id, Campaign>([Select (Select LeadId From CampaignMembers) From Campaign c Where Id = :campaignId]);
         for(Lead myLeads : scope) {
             CampaignMember newCM = new CampaignMember(
             CampaignId = campaignId,
             LeadId = myLeads.Id,
             status = 'Added' );

                 if (!cmMap.containsKey(myLeads.Id)) {
                     cm.add(newCM); 
                     collsize = cm.size();
                 }
         }

         try {
             Database.insert(cm); 
         } catch (DmlException ex) {
            System.Debug('Insert failed ' + ex);
         }        
    }

    global void finish(Database.BatchableContext BC) {
        AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed,  TotalJobItems, CreatedBy.Email From AsyncApexJob Where Id = :BC.getJobId()];
        // Send an email to the Apex job's submitter notifying of job completion.
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        String[] toAddresses = new String[] {a.CreatedBy.Email};
        mail.setToAddresses(toAddresses);
        mail.setSubject('Add to Campaign ' + a.Status);
        String campaignURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + campaignId;
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures. ' + 'Link to Campaign: ' + campaignURL);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }
}

Test Class

@isTest
public class BatchAddToCampaignTest
{
    static testMethod void testMethod1()
    {
        List<Lead> lstCM= new List<Lead>();
        for(Integer i=0 ;i <1;i++){
            Lead myLead = new Lead();
            myLead.Id = '00Q1U00000KqFcDUAV';
            lstCM.add(myLead);
            Integer collSize = lstCM.size(); 
            System.debug('List Collection Size is ' + collSize);
                {

                System.debug('Start Set');
                Set<Id> leadIds = (new Map<Id,SObject>(lstCM)).keySet();
                System.debug('End Set');
                Integer collSizeSet = leadIds.size(); 
                System.debug('Set Collection Size is ' + collSizeSet);
                Id workingCampaignId = '7011U000000RWRAQA4';

                Test.startTest();

                //BatchAddToCampaign ba = new BatchAddToCampaign(workingCampaignId, leadIds);
                DataBase.executeBatch(new BatchAddToCampaign(workingCampaignId, leadIds));

                Test.stopTest();  
                }
            }

    }
}
2
  • It won't execute because you don't have any data. You need to update the test to insert some data before you run the batch.
    – Phil W
    Commented Feb 23, 2020 at 16:45
  • 1
    You also have a for loop running the Test.startTest() and stopTest(). I know it's a for loop that only runs one time, the Test start and stop, as well as the executeBatch should definitely not be running in a loop block context Commented Feb 23, 2020 at 18:34

1 Answer 1

6

Your unit tests execute in an isolated data environment and cannot see the records with the hard-coded Salesforce Ids you've included. Hence, your query returns no records.

Your unit tests should always generate their own data within test context. See How do I write an Apex unit test? for links to great resources on how to do this well.

You must log in to answer this question.

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