I currently have a Batchable
process that will send emails to some users:
global class ExpiryNotificationHandler implements Database.Batchable<sObject> {
global System.Iterable<sObject> start(Database.BatchableContext context) {
return [SELECT Id, Email, Name FROM User WHERE UserRole.Name = 'Regional Manager'];
}
global void execute(Database.BatchableContext context, List<User> users) {
EmailTemplate emailTemplate = [SELECT Id FROM EmailTemplate WHERE DeveloperName = 'Expiry_Notification' LIMIT 1];
for (User u: users) {
Messaging.SingleEmailMessage email = Messaging.renderStoredEmailTemplate(emailTemplate.Id, UserInfo.getUserId(), u.Id);
email.setSaveAsActivity(false);
email.setToAddresses(new List<String> { u.Email });
Messaging.SendEmailResult[] mailResult = Messaging.sendEmail(new List<Messaging.Email> { email });
}
}
global void finish(Database.BatchableContext context) {
// Call another process
}
}
The email grabs some extra data and prints it in a table in the email.
I can create a unit test what will create the required data for the process to run, the problem is that the unit test fails at Messaging.renderStoredEmailTemplate()
with the error:
System.EmailTemplateRenderException: EMAIL_TEMPLATE_MERGEFIELD_ERROR: List has no rows for assignment to SObject
My suspicion is that even though I have created the correct data for the unit test, when it is trying to render the email, it is not running in the same context as the unit test. Thus it can't see any of the test data that I have created.
One way that I can work around this is that I can annotate my test method with SeeAllData = true
but given that my org might not have the data that is needed for the process/email (I am currently testing this in my dev org), I don't think the is the best solution.
Is there a way that I can create test data in a unit test and make it visible to when the visualforce email template when running a unit test?
I have tried using the Messaging.renderStoredEmailTemplate()
function as well as configuring the Messaging.SingleEmailMessage()
object:
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setTemplateId(emailTemplate.Id);
mail.setWhatId(u.Id);
mail.setTargetObjectId(UserInfo.getUserId());
mail.setSaveAsActivity(false);
mail.setToAddresses(new List<String> { u.Email });