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
feelsfdcfeelsfdc 

Test method fails

HI,

 

I have test method  and it's getting failing with this error : "System.Exception: No more than one executeBatch can be called from within a testmethod.  Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation."

 

this is the case when I run test case in Full sandbox. I am not getting problems in Development Sandbox.

 

Any help on this would be appreciated.

 

Thanks

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

You don't need the runTestMethod boolean in your test class.

 

Change the runTestMethod in the batch apex to public visibility, then in your test method:

 

 

Batch7DayDSULead dsulead = new Batch7DayDSULead(selectedday);
dsuLead.runTestMethod=true;
Database.executeBatch( dsulead);

 

should do the trick.

 

All Answers

bob_buzzardbob_buzzard

This sounds like the query backing your batch apex is returning more than 200 records - as you are getting this problem in a full sandbox, is the real data being pulled into the test?

 

I usually get around this by creating a Boolean testMode property in the batch apex class and setting this from the unit test.  Then in the start method, if testMode is true I append a limit 200 to the query.

feelsfdcfeelsfdc

Hi Bob,

 

Boolean testMode property ? May I know how to use this.

 

I took a Boolean variable in the testclass and initialise it to true. where as in the Batch Apex, I took same variable and checking against true to append  limit to the query. But I am getting system.NullPointer Exception. I know I am doing wrongly..

 

Can you help me how to do that?

 

Thanks in advance..

bob_buzzardbob_buzzard

Can you post your code?

feelsfdcfeelsfdc

Here My Batch Apex:

 

/*
 *  Cloning 7Day DSU lead into New Field Lead  
 */
global class Batch7DayDSULead implements Database.Batchable<SObject>{
     
    global static ID dsuTransferedLeadQueueId;
    public ID assignedOfficeName;
    public String districtName;
    public String marketName;
    static Boolean runTestMethod = false;
    
    public Integer selectedDay;
    
    global Batch7DayDSULead(Integer Day){
        selectedDay = Day;
    }
    
    global Batch7DayDSULead(){
        selectedDay = 7;
      //  runTestMethod = false;
    }
          
    global Database.Querylocator start(Database.BatchableContext BC) {
        
        Integer numDays = selectedDay;                          			 // Set numDays to number of days back, example 7
	    numDays = numDays * -1;                                 			 // Now set it to negative for days back.  becomes -7
	    Datetime dt = System.now();                             			 // Get system date/time
	    dt = dt.addDays( numDays);                               			 // Add (subtact with negative) days from now
        String dtString = '' + dt;                               			 // Convert to a string
        String formattedString = dtString.replace( ' ', 'T') + '.000Z';      // Make it SOQL friendly 
        	    
    
  		// Query for 7 day old DSU leads
        String query = 'select '+
            '       Phone ,'+
            '       Campaign_Code__c ,'+
            '       Campaign__c ,'+
            '       City ,'+
            '       Country ,'+
            '       Customer__c ,'+
            '       Date_of_Birth__c ,'+
            '       Email ,'+ 
            '       FirstName ,'+
            '       Name ,'+
            '       Gender__c ,'+
            '       Home_Phone__c ,'+
            '       LastName ,'+
            '       Marital_Status__c ,'+ 
            '       Membership_Number__c ,'+
            '       Middle_Initial__c ,'+
            '       MobilePhone ,'+
            '       Nickname__c ,'+
            '       Preferred_Language_Lookup__c ,'+                       
            '       Preferred_Method_of_Contact__c ,'+
            '       State ,'+
            '       Street ,'+
            '       Work_Phone__c ,'+
            '       Product_Of_Interest__c ,'+
            '       PostalCode ' +        
            '  from Lead' +
            ' where createdDate < '+formattedString+
            '   and status in (\'New\',\'Attempting to Contact\') ' +
            '   and ( Sales_Channel__c = \'DSU Inbound\' or Sales_Channel__c = \'DSU Outbound\' ) ' +
            '   and isConverted = false ' ;
        
        system.debug('DEBUG>>>> query'+query);
        
        //trying to retrieve only 200 records for test method
    //    try{
        if(runTestMethod){
        	query = query + ' limit 200 order by createddate desc';
        	system.debug('Entered in this if');
        }
      //  }catch(System.NullPointerException e ){}
        system.debug(query);
        return Database.getQueryLocator( query);
        
    }

    global void execute(Database.BatchableContext BC, SObject[] scope){
            

        List<Lead> oldLeads = new List<Lead>();  
        Lead newLead;  
        List<Lead>newLeads = new List<Lead>(); 
        
        Id unAssignedOfficeName = [select id from Office__c where office_name__c ='Unassigned' limit 1].id;        
          
        
        //getting and setting values to new lead
        dsuTransferedLeadQueueId = [select id, name 
                                      from Group 
                                     where name = 'DSU Transferred Queue'].id; 
                                     
        Id recordTypeForNewLead = [Select id 
                             From RecordType  
                            where name ='P&C Field Lead Record Type'].id;  
                            
        Id recordTypeForOldLead = [select id
        							 from RecordType 
        							where name = 'DSU Forwarded to Field Record Type'].id;                                                            
               
        for ( SObject s : scope ) {
            Lead oldLead = (Lead) s;
            oldLeads.add( oldLead);
            
        }
        
        //Office_Zip_Assignment Map
        Map<String,Office_Zip_Assignment__c>ozaMap = new Map<String,Office_Zip_Assignment__c>();
        
        for(Office_Zip_Assignment__c oza:[select Postal_Code__c,
                                                 Office__c 
                                            from Office_Zip_Assignment__c 
                                           where Effective_Date__c < TODAY
                                             and (End_Date__c > TODAY or End_Date__c = null)]){
            ozaMap.put(oza.Postal_Code__c, oza);
         } 
         
         //officeMap
        Map<ID,Office__c> officeMap = New Map<ID,Office__c>();
        
        for (Office__c office  : [select id,
                                         District__r.Market__c, 
                                         District__c 
                                    from office__c ]){
            officeMap.put(office.id, office);
        }
         
            
        for(Lead oLead : oldLeads){
               
            if(ozaMap.containsKey(oLead.PostalCode)){
                    
                assignedOfficeName = ozaMap.get(oLead.PostalCode).Office__c;
            }
            else{
                 
                assignedOfficeName = unAssignedOfficeName; //if lead has no postalcode, assigning him to unassigned office 
            }
                                   
            if(officeMap.containsKey(assignedOfficeName)){
                
                districtName = officeMap.get(assignedOfficeName).District__c;
                marketName = officeMap.get(assignedOfficeName).District__r.Market__c;
                        
            }
        
            //cloning DSU lead
            newLead = oLead.Clone(false,true);  //do not copy the ID, but make a copy of all the details into a seperate object
            newLead.Leadsource = 'DSU Transferred';
            newLead.OwnerId = dsuTransferedLeadQueueId;
            newLead.Assigned_Office_name__c = assignedOfficeName;
            newLead.Original_Assigned_Office_Name__c = assignedOfficeName; 
            newLead.District__c = districtName;
            newLead.Market_Name__c = marketName;
            newLead.RecordTypeId = recordTypeForNewLead; 
            newLead.Sales_Channel__c = 'P&C Field Outbound';
            newLead.Original_Sales_Channel__c = 'P&C Field Outbound';
            newLead.status = 'New';
            newLead.Old_Lead__c = oLead.id; 
            newLead.Original_DSU_Lead_ID__c = oLead.id;
            
            newLeads.add(newLead);
            oLead.status = 'Fwd to Field';
            oLead.RecordTypeId = recordTypeForOldLead; //lock Fwd to Field record

        }
        insert newLeads; 
        update oldLeads; 
    
    }

    global void finish(Database.BatchableContext BC){
        System.debug( 'inside finish method');
        // Get the ID of the AsyncApexJob representing this batch job
        // from Database.BatchableContext.
        // Query the AsyncApexJob object to retrieve the current job's information.
        AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email
                            from AsyncApexJob 
                           where Id = :BC.getJobId()];
        System.debug( 'Got the AsyncApexJob info');
        // Send an email to the Apex job's submitter notifying of job completion.
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();  
		String runningUserEmail = [select email from User where id = :UserInfo.getUserId()].email;
        String[] toAddresses = new String[] { runningUserEmail};
        mail.setToAddresses(toAddresses);
        mail.setSubject('Batch 7Day DSU Leads ' + a.Status);
        mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.');
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }

}

 

and this is My Test Class:

 

 

 

@isTest
private class Batch7DayDSULeadTest {
        
   static testMethod void Batch7DayDSULeadTest() {
        
        Integer selectedday = -7;         
        
        Boolean runTestMethod;
        // add eligible Lead
        Lead lead = new Lead(firstName = 'Lasya', lastName = 'Sree', email = 'noreply@yahoo.com', 
                              LeadSource =  'Inbound', sales_Channel__c = 'DSU Inbound');
        insert lead;
        ID id = lead.id;
         
        Test.startTest();
        runTestMethod = true;
        Batch7DayDSULead dsulead = new Batch7DayDSULead(selectedday);
        Database.executeBatch( dsulead);
        Test.StopTest();

        System.AssertEquals(database.countquery('Select count()'
                                                           +' from Lead'
                                                           +' where status = \'New\'' 
                                                           +'   and Old_Lead__c = \''+id+'\''), 1);
                                                                   
    }
            
}

 

 

 

bob_buzzardbob_buzzard

You don't need the runTestMethod boolean in your test class.

 

Change the runTestMethod in the batch apex to public visibility, then in your test method:

 

 

Batch7DayDSULead dsulead = new Batch7DayDSULead(selectedday);
dsuLead.runTestMethod=true;
Database.executeBatch( dsulead);

 

should do the trick.

 

This was selected as the best answer
feelsfdcfeelsfdc

Thanks Bob.

Rahul SharmaRahul Sharma

Thanks a lot Mr. BOB,

It helped me too, smart solution..

RajiiiRajiii

Hi bob i met same scenario..

But whenever i call that static variable in my test method, it was raising the cause like "Class static variable cannot be accessed via object instance"..

what i do for this case.

salesforceapexsalesforceapex
Bob, I quick question around your comment. The test class doesn't see the Org data and only 1 lead is created, then why do we need to handle this with boolean. Default batch size is 200 which more than enough for this test to run. Could you please clarify