I'm at about 26% covered missing the Execute method for the most part doesn't appear to be firing.

Here is the code I have:

public class UpdateFutureCasesToNewStatus implements Database.Batchable<sObject>, Schedulable {
    public void execute(SchedulableContext sc) {
        UpdateFutureCasesToNewStatus myBatchObject = new UpdateFutureCasesToNewStatus(); 
        Id batchId = Database.executeBatch(myBatchObject,100);
    public Database.QueryLocator start(Database.BatchableContext BC) {
        // collect the batches of records or objects to be passed to execute
        return Database.getQueryLocator([Select Id, Status, Future_Date_for_Completion__c
                                         from Case Where Status = 'Pending - Future Date for Completion' 
                                         AND Future_Date_for_Completion__c = TODAY]);
    public void execute(Database.BatchableContext BC, List<Case> FutureCasesList) {
        // process each batch of records default size is 200
        For (Case CaseList: FutureCasesList){
            CaseList.Status = 'New';
            CaseList.Comments = 'Future Dated Case, being reassigned to the working queue.' ;
            CaseList.First_Team_Line__c = false;
            CaseList.Calc_SLA__c = false;
        try {               
            Update FutureCasesList ;
        } catch(Exception e) {
            System.debug('Error: '+ e);
            // execute any post-processing operations like sending email
            Messaging.SingleEmailMessage mail=new Messaging.SingleEmailMessage();
            String[] toAddresses = new String[] {'my@email.com'};
            mail.setSenderDisplayName('Apex error message');
            mail.setSubject('Error from Org : ' + UserInfo.getOrganizationName());
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    public void finish(Database.BatchableContext BC) {

Here is the code I'm using to cover in my unit test:

public class UpdateFutureCasesToNewStatusTest {
    @isTest static void testLogic() {
        List<Case> ListOfTestCases = new List<Case>();
        for(Integer i = 0; i < 10; i += 1) {
            Case TestCase = new Case();
            TestCase.Status = 'Pending - Future Date for Completion';
            TestCase.Subject = 'Test';
            TestCase.Future_Date_for_Completion__c = Date.today();
            TestCase.Comments = 'Updated By Automation';
        insert ListOfTestCases;
        UpdateFutureCasesToNewStatus sh1 = new UpdateFutureCasesToNewStatus();      
        String sch = '0 0 23 * * ?';
        system.schedule('Test check', sch, sh1);
  • please see this answer that elaborates on David Reed's answer – cropredy Aug 20 '20 at 22:12

You cannot effectively write an integration test against multi-leveled or nested asynchronous Apex, which is what you have here (Schedulable enqueuing Batchable).

Test.stopTest() will only force the first layer of asynchronous code to run synchronously. While you may see the other layer (the batchable) execute in logs, it's not really running within your unit test, which impacts your ability to (for example) write meaningful assertions.

You need to decompose the scheduled and batch layer and test them separately, with at least one unit test that directly calls Database.executeBatch(). We have an example with more details in the "Nested Asynchronous Code" section of How do I test asynchronous Apex?.


In the test you need to call the batch. I assume you expecting that the schedule from the test will run the batch but it is not always works as expected... Assume something in the SF infrastrucute... You should write in the test:

Database.executeBatch(new UpdateFutureCasesToNewStatus ());


Just a guess here...

One weird thing about scheduled contexts in tests - I think it actually fast forwards to the date to run the schedule. So the "Today" context may not be working.

One way to resolve this might be to just separate the test for the schedule method and the batch.

public static void batchTest(){
// set up data
database.executebatch(new UpdateFutureCasesToNewStatus());
// then another test just to cover those lines... 
// you don't REALLY need to test the scheduling functionality IMO

public static void scheduleTest(){
// really just for coverage
UpdateFutureCasesToNewStatus ufctns = new UpdateFutureCasesToNewStatus ();


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.