I have a process that needs to run once daily. It will first need to make a series of callouts to get information (sms email address) to update contacts, and it will then need to send emails using the updated contacts. The callouts may exceed 10, so I have designed a Batchable class that can find all the correct records, make the callouts in batches, and update the records. From the finish() method I want to invoke the method to send the emails.
Here's the rough outline:
global class Reminders_Schedulable implements Schedulable {
global void execute() {
// OMITTED: do a little setup work
// Run the batchable to make callouts and update contact's SMS email addresses
Database.executeBatch(new SMSGatewayUtil_Batchable(), SMSGatewayUtil.MAX_BATCH_SIZE);
}
global static void SendReminders() {
// send the actual reminders using the updated contacts
}
}
global class SMSGatewayUtil_Batchable
implements Database.Batchable<SObject>, Database.AllowsCallouts {
global Database.QueryLocator start(Database.BatchableContext bc) {
system.debug('&&&& SMSGatewayUtil_Batchable.start');
return Database.getQueryLocator(...);
}
global void execute(Database.BatchableContext bc, list<Contact> contacts) {
system.debug('&&&& SMSGatewayUtil_Batchable.execute');
SMSGatewayUtil.UpdateContactsSMSEmail(contacts);
update contacts;
}
global void finish(Database.BatchableContext bc) {
system.debug('&&&& SMSGatewayUtil_Batchable.finish');
Reminders_Schedulable.SendReminders();
}
}
So the scheduleable class's execute() method runs the batchable, which updates makes callouts and updates contacts; finally the batchable's finish() method calls a static method
to send the emails, using the updated contacts. Is there are reason why the schedulable's execute() method shouldn't be able to call the batchable()? I don't think there is, but thought I'd check.
The bigger question - is this testable as is? I have a test method that calls system.schedule to run the schedulable (in between startTest and stopTest). The execute() method is called, and I see the SMSGatewayUtil_Batchable constructor invocation on the executeBatch() line in the log, but the batchable doesn't appear to run - the debug statements in the batchable class do not even appear in the log. There's also no error messages.
Update: As I failed to mention originally, my test class is setting up a mock interface for the callout. The question that I have is that the Database.Batchable is being constructed but not invoked - as shown in my outline above, each method in the Batchable has a debug statement, and none of them are showing up in the debug log - not even the start() method.