+ Start a Discussion
Patrick G. BrownPatrick G. Brown 

Need Help with System.NoSuchElementException: Iterator has no more elements Error Message

I'm working on a test for my batch process.  The batch works fine, however, I'm getting an error message in my test class.  Can anyone help?

Here is the batch I'm executing:
 
/**
This batch process will be triggered when a Campaign is deactivated and will stamp the Campaign with the dateTime value.
This batch will kick off two processes that also update Leads and CampaignMembers with the appropriate values.

*/

global class batchDeactivateCampaignCM implements Database.Batchable<sObject>,Database.Stateful{  
   
  
   global final DateTime nowStamp;
   //global final Integer nowStamp;
   global final Integer currentNowDateTime;  
   global List<Campaign> recordsToUpdate;
   
   
   global batchDeactivateCampaignCM(Integer nowDateTime)  
   {  
     currentNowDateTime = nowDateTime;  
     nowStamp = datetime.now();  
     recordsToUpdate = new List<Campaign>();  
   }  
   global Database.QueryLocator start(Database.BatchableContext BC)  
   {  
    return Database.getQueryLocator('Select id, Name, IsActive, Deactivate_Date__c from Campaign WHERE IsActive = FALSE AND Deactivate_Date__c = NULL');
    //Patrick, add this Where clause back in WHERE IsActive = FALSE AND Deactivate_Date__c = NULL
   }  
   global void execute(Database.BatchableContext BC, List<Campaign> scope)  
   {  
    for(Campaign c: scope)  
    {  if(c.IsActive == False && c.Deactivate_Date__c ==NULL){
     c.Deactivate_Date__c = nowStamp;  
    }
    }
    recordsToUpdate.addAll(scope);   
    update scope;  
   }  
    global void finish(Database.BatchableContext BC)
    {
	// 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()];
	// 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('Batch Process to Deactivate Campaigns ' + a.Status);
	mail.setPlainTextBody
	('The batch Apex job batchDeactivateCampaignCM processed ' + a.TotalJobItems +
	' batches with '+ a.NumberOfErrors + ' failures.');
	Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
	
System.debug('DateTimeStamped : '+ nowStamp);
System.ScheduleBatch(new batchDeactivateCampaignMembers(recordsToUpdate),'Batch to Update CampaignMembers :'+String.valueOf(Datetime.now()),1,50);  
System.ScheduleBatch(new batchDeactivateLeads(recordsToUpdate),'Batch to Update Leads :'+String.valueOf(Datetime.now()),2,50);   
	
	}
}

My test class is below. 

I'm getting an error on line 18, col 1 stating ( campList.add((Campaign)QIT.next()); ).  The error reads: "System.NoSuchElementException: Iterator has no more elements
Class.Database.QueryLocatorIterator.next: line 52, column 1
Class.batchDeactivateCMLeadTest.testBatch: line 18, column 1"
 
@IsTest  
 class batchDeactivateCMLeadTest  
 {  
 static testMethod void testBatch()  
 {  
  Campaign c = new Campaign(Name='Test Batch Campaign');  
  insert c;  
  Lead l = new Lead(firstname ='Testbatchfirst', lastname = 'Testbatchlast', company = 'Testbatchcompany', National_Provider_Number_NPN__c = '12354868541');  
  insert l;
  CampaignMember cm = new CampaignMember(CampaignId = c.id, LeadId = l.id);
  insert cm;
  Database.BatchableContext BC;  
  batchDeactivateCampaignCM bdc = new batchDeactivateCampaignCM(50);  
  bdc.start(BC);  
  Database.QueryLocator QL = bdc.Start(BC);  
  List<Campaign> campList = new List<Campaign>();  
  Database.QueryLocatorIterator QIT = QL.iterator();  
  campList.add((Campaign)QIT.next());  
  bdc.execute(BC,campList);  
  bdc.finish(BC);  
//   System.assertEquals([Select 
//                         id,
//                         Name
//                         from Campaign
//                         where Name = 'Test Batch Campaign']);  
  Database.BatchableContext BC_new;  
  batchDeactivateCampaignMembers bdcm = new batchDeactivateCampaignMembers([Select Id from Campaign]);  
  bdcm.start(BC_new);  
  Database.QueryLocator QL_new = bdcm.Start(BC_new);  
  List<CampaignMember> campaignMem = new List<CampaignMember>();  
  Database.QueryLocatorIterator QIT_new = QL_new.iterator();  
  campaignMem.add((CampaignMember)QIT_new.next());  
  bdcm.execute(BC_new,campaignMem);  
  bdcm.finish(BC_new);  

  Database.BatchableContext BC_new2;  
  batchDeactivateLeads bdl = new batchDeactivateLeads([Select Id from Campaign]);  
  bdl.start(BC_new2);  
  Database.QueryLocator QL_new2 = bdl.Start(BC_new);  
  List<Lead> campaignLead = new List<Lead>();  
  Database.QueryLocatorIterator QIT_new2 = QL_new2.iterator();  
  campaignLead.add((Lead)QIT_new.next());  
  bdl.execute(BC_new,campaignLead);  
  bdl.finish(BC_new);

 }  
 }

 
Best Answer chosen by Patrick G. Brown
Amit Chaudhary 8Amit Chaudhary 8
Please try below code
@IsTest  
class batchDeactivateCMLeadTest  
{  
	static testMethod void testBatch()  
	{  
		Campaign c = new Campaign(Name='Test Batch Campaign' , IsActive = FALSE);  
		insert c;  
		
		Lead l = new Lead(firstname ='Testbatchfirst', lastname = 'Testbatchlast', company = 'Testbatchcompany', National_Provider_Number_NPN__c = '12354868541');  
		insert l;
		
		CampaignMember cm = new CampaignMember(CampaignId = c.id, LeadId = l.id);
		insert cm;
		
		batchDeactivateCampaignCM bdc = new batchDeactivateCampaignCM(50);  
		Database.executeBatch(bdc);
		
		
		
	}  
}

Let us know if this will help you
 

All Answers

Amit Chaudhary 8Amit Chaudhary 8
Please try below code
@IsTest  
class batchDeactivateCMLeadTest  
{  
	static testMethod void testBatch()  
	{  
		Campaign c = new Campaign(Name='Test Batch Campaign' , IsActive = FALSE);  
		insert c;  
		
		Lead l = new Lead(firstname ='Testbatchfirst', lastname = 'Testbatchlast', company = 'Testbatchcompany', National_Provider_Number_NPN__c = '12354868541');  
		insert l;
		
		CampaignMember cm = new CampaignMember(CampaignId = c.id, LeadId = l.id);
		insert cm;
		
		batchDeactivateCampaignCM bdc = new batchDeactivateCampaignCM(50);  
		Database.executeBatch(bdc);
		
		
		
	}  
}

Let us know if this will help you
 
This was selected as the best answer
Patrick G. BrownPatrick G. Brown
Amit, thanks for this help.  This allowed me to get past my error and continue working with my test class.  Truly appreciate it!