I am trying to test Schedulable
class which is designed to only run once.
Because it's only runs once, I need to test that the System.abortJob
is working correctly.
I am using this code to test:
Test.startTest();
Id jobId = FaxScheduledJob.scheduleJob(whatId, whoId, templateName, 1);
Test.stopTest();
Which calls this static helper method to create and schedule the job:
public static Id scheduleJob(Id whatId, Id whoId, String templateName, Decimal numOfAttempts) {
FaxScheduledJob job = new FaxScheduledJob(whatId, whoId, templateName, numOfAttempts);
return System.Schedule('Fax Job', schedule(), job);
}
But I get an error when it does the callout to send the fax:
You have uncommitted work pending. Please commit or rollback before calling out
I've looked everywhere and I cannot find any DML that could be causing this.
I suspect that a CronTrigger
or AsyncApexJob
record is created when I schedule the job, and that is what is causing the error message, but I am not certain.
When I test the Schedulable
without actually scheduling it:
SchedulableContext context = new SchedulableContextMock();
Test.startTest();
TwilioFaxScheduledJob job = new TwilioFaxScheduledJob(whatId, whoId, templateName, 1);
job.execute(context);
Test.stopTest();
It does not error.
Here is the full FaxScheduledJob
class:
public with sharing class FaxScheduledJob implements Schedulable {
private Id whatId;
private Id whoId;
private String templateName;
private Decimal numOfAttempts;
public FaxScheduledJob(Id whatId, Id whoId, String templateName, Decimal numOfAttempts) {
this.whatId = whatId;
this.whoId = whoId;
this.templateName = templateName;
this.numOfAttempts = numOfAttempts;
}
public void execute(SchedulableContext context) {
try {
// sendFaxAsync is a future method
FaxService.sendFaxAsync(whatId, templateName, whoId, true, numOfAttempts);
abortJob(context.getTriggerId());
} catch (Exception error) {
System.debug(LoggingLevel.ERROR, error);
}
}
private static void abortJob(Id jobId) {
System.runAs(getAdminUser()) {
if (jobId != null) {
System.abortJob(jobId);
}
}
}
public static Id scheduleJob(Id whatId, Id whoId, String templateName, Decimal numOfAttempts) {
FaxScheduledJob job = new FaxScheduledJob(whatId, whoId, templateName, numOfAttempts);
return System.Schedule('Fax Retry Job', schedule(), job);
}
private static String schedule() {
String hour;
String min;
if (Datetime.now().minute() >= 44) {
hour = String.valueOf(Datetime.now().hour() + 1);
min = String.valueOf(Datetime.now().minute() - 44);
} else {
hour = String.valueOf(Datetime.now().hour());
min = String.valueOf(Datetime.now().minute() + 15); // make this random number between 15 and 30
}
String ss = String.valueOf(Datetime.now().second());
String nextFireTime = ss + ' ' + min + ' ' + hour + ' * * ?';
return nextFireTime;
}
private static User getAdminUser() {
User admin = new User();
admin.Id = 'xxxxxxxxxxxx';
return admin;
}
}
Question
- How can I test this
Schedulable
and confirm that the job was aborted?