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
Ally Abdool Latiff MohabuthAlly Abdool Latiff Mohabuth 

need help to write a test class for batch finish method

Hello, i have a batch class. I need a test class for my finish method which send email. Here are my codes:
global void finish(Database.BatchableContext BC) {
        system.debug('accountsMap: ' + accountsMap);
        if(accountsMap != null
           && accountsMap.size() > 0){
            
            Messaging.SingleEmailMessage mail = null;   
            List<Messaging.singleEmailMessage> mailsList = new List<Messaging.singleEmailMessage>();
            Id contactId = null;
               
      		for(Order__c ord : accountsMap.values()){
                if(ord.Account__r.Carer__c != null && ord.Account__r.Carer__r.IsCustomerPortal){
                    contactId = (ord.Account__r.Carer__r.PersonContactId != null) ? ord.Account__r.Carer__r.PersonContactId :null;
                }else if(ord.Account__r.IsCustomerPortal != null){
                    contactId = (ord.Account__r.PersonContactId != null) ? ord.Account__r.PersonContactId :null;
                }
                
                if(contactId != null){
                    List<EmailTemplate> template = [SELECT Id FROM EmailTemplate WHERE DeveloperName = 'Stock_Due_Reminder' LIMIT 1];
                    
                    if(template.size() > 0){
                        mail = new Messaging.SingleEmailMessage(); 
                        mail.setTemplateId(template[0].Id);
                        mail.setTargetObjectId(contactId);
                        mailsList.add(mail);
                    }
                }
            }

 
Amit Chaudhary 8Amit Chaudhary 8
Your finish method will call automaticly from below code.
 
yourBatchJob obj = new yourBatchJob ();
            DataBase.executeBatch(obj);

Make sure you accountsMap should contain some value. Can you please post your full code
Please check below post for some more information
1) http://amitsalesforce.blogspot.com/2016/02/batch-apex-in-salesforce-test-class-for.html
 
Ally Abdool Latiff MohabuthAlly Abdool Latiff Mohabuth
global class StockCheckBatch implements Database.Batchable<sObject>, Database.Stateful {

	private Map<Id,User> userMap;
	private static final Set<String> closedStatuses = new Set<String>{'Pending'};
    global final Map<Id, Order__c> accountsMap = null;

    global StockCheckBatch(){
        
        accountsMap = new Map<Id, Order__c>();
    }
    
	global Database.QueryLocator start(Database.BatchableContext BC) {
		
		Date initialSend 	= Date.today();
		Date reminder1 		= Date.today().addDays(-4);
		Date reminder2 		= Date.today().addDays(-6);

		return Database.getQueryLocator(
			[
				SELECT
						Id,
						Online_Contact_Email__c,
						Send_Stock_Check_Open_Email__c,
						Send_Stock_Check_Reminder_1_Email__c,
						Send_Stock_Check_Reminder_2_Email__c,
						Stock_Check_Window_Open_Stamped__c,
						Account__r.IsCustomerPortal,
						Account__c,
						Account__r.PersonContactId,
						Account__r.Carer__r.IsCustomerPortal,
						Account__r.Carer__c,
						Account__r.Carer__r.PersonContactId,
                		               TECH_IsBatch__c
				FROM
                 Order__c 
				WHERE
					((
						Stock_Check_Window_Open_Stamped__c = :initialSend
					AND
						Send_Stock_Check_Open_Email__c = false
					)
					OR
					(
						Stock_Check_Window_Open_Stamped__c = :reminder1
					AND
						Send_Stock_Check_Reminder_1_Email__c = false
					)
					OR
					(
						Stock_Check_Window_Open_Stamped__c = :reminder2
					AND
						Send_Stock_Check_Reminder_2_Email__c = false
					))
					AND
					(
						Account__r.IsCustomerPortal = true
					OR
						Account__r.PMS_Carer__r.IsCustomerPortal = true
					)
					AND
						(Status__c IN :closedStatuses)
			]);
	}

   	global void execute(Database.BatchableContext BC, List<Order__c> stockChecks) {
   		doLogic(stockChecks);
	}
	
	global void finish(Database.BatchableContext BC) {
        system.debug('accountsMap: ' + accountsMap);
        if(accountsMap != null
           && accountsMap.size() > 0){
            
            Messaging.SingleEmailMessage mail = null;   
            List<Messaging.singleEmailMessage> mailsList = new List<Messaging.singleEmailMessage>();
            Id contactId = null;
               
      		for(Order__c ord : accountsMap.values()){
                if(ord.Account__r.Carer__c != null && ord.Account__r.Carer__r.IsCustomerPortal){
                    contactId = (ord.Account__r.Carer__r.PersonContactId != null) ? ord.Account__r.Carer__r.PersonContactId :null;
                }else if(ord.Account__r.IsCustomerPortal != null){
                    contactId = (ord.Account__r.PersonContactId != null) ? ord.Account__r.PersonContactId :null;
                }
                
                if(contactId != null){
                    List<EmailTemplate> template = [SELECT Id FROM EmailTemplate WHERE DeveloperName = 'Stock_Due_Reminder' LIMIT 1];
                    
                    if(template.size() > 0){
                        mail = new Messaging.SingleEmailMessage(); 
                        mail.setTemplateId(template[0].Id);
                        mail.setTargetObjectId(contactId);
                        mailsList.add(mail);
                    }
                }
            }

	@TestVisible
	private void doLogic(List<Order__c> stockChecks) {
       
		Date today = Date.today();
   		List<Order__c> updatedStockChecks = new List<Order__c>();

   		Set<Id> contactIds = new Set<Id>();
   		for (Order__c stockCheck : stockChecks) {
   			
   			if (hasCarerUser(stockCheck)) {
   				contactIds.add(stockCheck.Account__r.Carer__r.PersonContactId);
   			}
   			
   			else if (hasPatientUser(stockCheck)) {
   				contactIds.add(stockCheck.Account__r.PersonContactId);
   			}
   		}

   		// Create a map with the person contact Id as key and the user as the value. Query for email address.
   		userMap = new Map<Id,User>();
   		for (User theUser : [SELECT ContactId, Email FROM User WHERE ContactId IN :contactIds]) {
   			userMap.put(theUser.ContactId, theUser);
   		}

   		for (Order__c stockCheck : stockChecks) {

   			Boolean updated = false;

   			Date initialSend 	= stockCheck.PStock_Check_Window_Open_Stamped__c;
   			Date reminder1 		= stockCheck.Stock_Check_Window_Open_Stamped__c.addDays(4);
   			Date reminder2 		= stockCheck.Stock_Check_Window_Open_Stamped__c.addDays(6);

   			// Stock check opening day: 16 days before delivery.
   			if (initialSend == today) {
   				stockCheck.Send_Stock_Check_Open_Email__c = true;
   				updated = true;
   			}
   			// Reminder 1: 12 days before delivery.
   			else if (reminder1 == today) {
   				stockCheck.Send_Stock_Check_Reminder_1_Email__c = true;
   				updated = true;
   			}
   			// Reminder 2: 10 days before delivery.
   			else if (reminder2 == today) {
   				stockCheck.Send_Stock_Check_Reminder_2_Email__c = true;
   				updated = true;
   			}

   			
   			if (hasCarerUser(stockCheck) || hasPatientUser(stockCheck)) {
   				stockCheck.Online_Contact_Email__c = getEmail(stockCheck);
   			}
   			// Neither
   			else {
   				updated = false;
   			}
			
   			if (updated) {
                stockCheck.TECH_IsBatch__c = true;
   				updatedStockChecks.add(stockCheck);
              
                if(accountsMap != null){
                    accountsMap.put(stockCheck.Account__c, stockCheck);
                }
   			}
   		}

   		update updatedStockChecks;
	}

	private Boolean hasCarerUser(Order__c stockCheck) {
		return (stockCheck.Account__r.Carer__c != null && stockCheck.Account__r.Carer__r.IsCustomerPortal);
	}

	private Boolean hasPatientUser(Order__c stockCheck) {
		return (stockCheck.Account__r.IsCustomerPortal);
	}

	private String getEmail(Order__c stockCheck) {

		Id contactId;

		if (hasCarerUser(stockCheck)) {
			contactId = stockCheck.Account__r.Carer__r.PersonContactId;
		}
		else if (hasPatientUser(stockCheck)) {
			contactId = stockCheck.Account__r.PersonContactId;
		}
		else {
			return null;
		}

		if (userMap!=null && userMap.containsKey(contactId)) {
			return userMap.get(contactId).Email;
		}
		else {
			return null;
		}
	}
	
}

My full code