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
RemoteErrorsBatch
and invocation ofexecute()
. 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.RemoteErrorsServiceImpl.processConnectFailures()
. In this second testmethod, you will use yourTest.setMock(WebServiceMock.class, new RemoteErrorsBatchTest.RemoteErrorsMockImpl());
The mock class needs to return a list of mocked
RemoteSystemFailure
objects.