[SalesForce] testing future with callout from schedulable class

I'm definitely missing something.
How do I test Schedulable class with a future method that does a callout?
I have 100% code coverage of the Schedulable class but 0% of my service.The test fails as no Error_Log__c object is inserted.
How should I test it correctly?

1) A schedulable class

public class  RemoteErrorsBatch implements Schedulable, Database.AllowsCallouts {
    public void execute(SchedulableContext sc) {
         RemoteErrorsServiceImpl.processConnectFailures(); 
    }
}

2) A service with SOAP callout

@future(callout = true)
public static void processConnectFailures(){
    RemoteSystemFailure[] lFailures = RemoteErrorsServiceImpl.getRemoteSystemFailure();
    List<Error_Log__c> lErrors = new List<Error_Log__c> ();
    for(RemoteSystemFailure oFailure  : lFailures){
        lErrors.add(new Error_Log__c( Description__c = oFailure.msg);
    }
    insert lErrors;
}

3) A failing test class

Test.startTest();
Test.setMock(WebServiceMock.class, new RemoteErrorsBatchTest.RemoteErrorsMockImpl());
String CRON_EXP = '0 00 * * * ?';
String jobId = System.schedule('RemoteErrorsBatch',CRON_EXP,new RemoteErrorsBatch());
Test.stopTest();
List<Error_Log__c> lErrors  = [SELECT Description__c FROM Error_Log__c];
System.assertEquals(1, lErrors.size());

Best Answer

I tend to break this up into two testmethods

  1. Test the construction of RemoteErrorsBatch and invocation of execute(). This is really just code coverage as you can guarantee that SFDC will invoke the execute() method at the appointed time so you don't have to assert that this will happen.
  2. Test the invocation of static method RemoteErrorsServiceImpl.processConnectFailures(). In this second testmethod, you will use your Test.setMock(WebServiceMock.class, new RemoteErrorsBatchTest.RemoteErrorsMockImpl());

The mock class needs to return a list of mocked RemoteSystemFailure objects.

Related Topic