Looking for some help/advice in writing a test class. The class I need to test is an apex class to schedule a report that needs to be sent to an external email address once a month as a .csv attachment. I was able to build the test class using some advice from an old post on the dev community; I found the solution in TESTOURSFDC's comment to work sufficiently for us. Copy of my code below.
What I'm struggling with is how to test that an email has been sent. The SF documentation for scheduled apex classes are all built with regular SF maintenance use cases (e.g. create tasks on opps that fulfill xyz criteria once a month), so their test classes are easy to re-create (query for tasks with related WhatIds). I've never worked with apex to send emails before, so I'm admittedly quite unfamiliar with the methods and metadata available.
Has anyone tested something similar to this that could help me out?
Thanks!!
Class (updated):
global class reportExporter implements System.Schedulable {
global void execute(SchedulableContext sc) {
ApexPages.PageReference report = new ApexPages.PageReference('/00OXXXXXXXXXXXX?csv=1');
Messaging.EmailFileAttachment attachment = new Messaging.EmailFileAttachment();
attachment.setFileName('Report.csv');
//use getContent() only if not a test, otherwise test will fail
//http://salesforce.stackexchange.com/questions/97223/test-fails-because-of-testmethod-do-not-support-getcontent-call
if(!test.isRunningTest()){
attachment.setBody(Blob.valueof(report.getContent().toString()));
} else {
attachment.setBody(Blob.valueof('TEST BODY'));
}
attachment.setContentType('text/csv');
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
message.setFileAttachments(new Messaging.EmailFileAttachment[] { attachment } );
message.setSubject('Report');
message.setPlainTextBody('The report is attached.');
message.setToAddresses( new String[] { 'name@example.com' } );
message.setBccAddresses( new String[] { 'name@example.com' } );
Messaging.sendEmail( new Messaging.SingleEmailMessage[] { message } );
List<Messaging.SendEmailResult> results = Messaging.SendEmail(new Messaging.Email[] { message });
System.debug(results);
if (!results.get(0).isSuccess()) {
System.StatusCode statusCode = results.get(0).getErrors()[0].getStatusCode();
String errorMessage = results.get(0).getErrors()[0].getMessage();
}
}
}
Test Class:
@isTest
private class testReportExporter {
// CRON expression: midnight on March 15 2022
// Because this is a test, job executes immediately after Test.stopTest() regardless of date
public static String CRON_EXP = '0 0 0 15 3 ? 2022';
static testmethod void test() {
Test.startTest();
reportExporter re = new reportExporter();
// Schedule the test job
String jobId = System.schedule('ScheduleApexClassTest',
CRON_EXP, re);
// Get the information from the CronTrigger API object
CronTrigger ct = [SELECT Id, CronExpression, TimesTriggered,
NextFireTime
FROM CronTrigger WHERE id = :jobId];
// Verify the expressions are the same
System.assertEquals(CRON_EXP,
ct.CronExpression);
// Verify the job has not run
System.assertEquals(0, ct.TimesTriggered);
// Verify the next time the job will run
System.assertEquals('2022-03-15 00:00:00',
String.valueOf(ct.NextFireTime));
// Verify the scheduled job hasn't run yet.
Integer beforeInvocations = Limits.getEmailInvocations();
System.assertEquals(0,beforeInvocations,'no email sent');
//Verify class results are not false
System.debug(re);
Test.stopTest();
}
}