3

I need help writing test cases for an email batch job. In the batch job, the users associated with the Franchisee__c field (a Lookup to User) from the custom object Store_App_Proc__c are selected and emails are sent to each user. The problem is that I am not sure how to structure my test class or what to assert for after running the batch.

The following is the code of the email batch job:

global class Store_App_Proc_EmailBatchJob implements Database.Batchable<sObject>, Database.Stateful{  

global Store_App_Proc__c sap;
global Id templateId; 

global Store_App_Proc_EmailBatchJob(Store_App_Proc__c insap){  
sap = insap;
templateId = [SELECT id, name FROM EmailTemplate WHERE developername = 'Email_to_FR'].id;   }

global Database.QueryLocator start(Database.BatchableContext BC){ 

Store_App_Proc__c fr = [Select Franchisee__c From Store_App_Proc__c WHERE id =: sap.id limit 1][0];

String query = 'SELECT Id FROM User WHERE Id= \'' + String.escapeSingleQuotes(fr.Franchisee__c) + '\'';

return Database.getQueryLocator(query);

}

global void execute(Database.BatchableContext BC, List<User> scope){  
for(User user : scope){   // send email per user   Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();   email.setTemplateId(templateId);   email.setReplyTo('example@example.com');   email.setSenderDisplayName('AGI Development');     email.setTargetObjectId(user.Id);    email.setWhatId(sap.Id);   email.setSaveAsActivity(false);   Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email});   } }

global void finish(Database.BatchableContext BC){} }

This is what I have so far for the test case:

@isTest
private class Store_App_Proc_EmailBatchJob_Test {  
public static testMethod void emailBatchJobTest(){   

Id templateId = [SELECT id, name FROM EmailTemplate WHERE developername = 'Email_to_FR'].id;

Account acct = new Account();  
acct.Name = 'test1';  
acct.AGI_Territory__c= 'Europe';  
acct.Sub_Territory__c = 'Western Europe';  
acct.AGI_Master_Country__c= 'Portugal'; 
acct.AGI_Partner_Account__c = 'ZT Two Image'; 

insert acct;   

// setting all the fields required for Store_App_Proc__c object 
Store_App_Proc__c storeAppProc = new Store_App_Proc__c(AGI_Account__c = acct.id); 
storeAppProc.AGI_Customer_Name__c = 'ALDO/ZT Two Image/Portugal';   
 //... 
 RecordType rt1 = [Select ID, Name ,DeveloperName From RecordType Where sObjectType = 'Store_App_Proc__c' and DeveloperName ='AGI_SAP_InitialStep' limit 1][0];  
 storeAppProc.RecordTypeId = rt1.id;   

insert storeAppProc;   

test.startTest();  

//initiating an instance of the batch job   
Store_App_Proc_EmailBatchJob b = new Store_App_Proc_EmailBatchJob(storeAppProc);  

test.stopTest();  

// what to assert?   

}
1

Well, first you'll want to actually fire the batch job like so

Store_App_Proc_EmailBatchJob b = new Store_App_Proc_EmailBatchJob(storeAppProc);
Database.executeBatch(b);
Test.stopTest();

Then for your assertions, I think there's a way to query for the sent emails. I'll look into it and update this.

update I couldn't find that, but what you could do is declare a class-level List<Messaging.SendEmailResult> and add each of your Messaging.SendEmailResult[] r values to it. Then in the test, you can loop through the results of b.fancylist and assert whatever you want about their state and integrity.

1

Note that the emails won't be sent in a testmethod anyway so there is no way to assert they are sent. An alternative to consider is for the batch class execute() to update an SObject with some boolean sendEmail__c to true and then a workflow is triggered to

  • send the email via an email alert
  • update the sendEmail__c back to false
  • create a task under the SObject indicating the email was sent

Your testmethod can verify that the Task was created and hence, implicitly verify that the workflow ran and its actions (including email alert) were executed. You also get the benefit of an completed Activity under the SObject indicating that an action happened, improving traceability and diagnostics

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.