I'm confused in Apex Specialist and do not understand how to test scheduled job that uses a callout.
Hi
I'm confused in Apex Specialist.
One of the requirements is to create a unit test WarehouseCalloutServiceTest.
There is a condition:
"Ensure that your code operates as expected in the scheduled context by validating that it executes after Test.stopTest() without exception.
Also assert that a scheduled asynchronous job is in the queue. The test classes for the callout service and scheduled test must also have 100% test coverage."
So I must use `System.schedule`
@isTestpublic class WarehouseCalloutServiceTest {
@isTest static public void warehouseCalloutServiceTest() {
Test.startTest();
Test.setMock(HttpCalloutMock.class, new WarehouseCalloutServiceMock());
// Schedule the test job
String jobId = System.schedule(
'WarehouseCalloutServiceTest',
'0 0 0 15 3 ? 2042',
new WarehouseSyncSchedule()
);
Assert.isNotNull(jobId, 'JOB ID must be not null.');
Test.stopTest();
// Now schedulled job is finished and I can test result via Assert
...
Assert...
Now let's look at the `WarehouseCalloutServiceTest` class
public class WarehouseSyncSchedule implements Schedulable {
public void execute(SchedulableContext ctx) {
WarehouseCalloutService srv = new WarehouseCalloutService();
srv.updateProducts(); // there is a callout inside this method
}
}
the solution does not work, it throws an exception `System.CalloutException: Callout from scheduled Apex not supported`.
So I must use asynchronous queue
public void execute(SchedulableContext ctx) {
WarehouseCalloutService srv = new WarehouseCalloutService();
System.enqueueJob(srv);
}
public class WarehouseCalloutService implements Queueable, Database.AllowsCallouts {
public void execute(QueueableContext context) {
this.updateProducts(); // there is a callout inside this method
}
}
And now I have 100% test coverage, but any asserts do not pass.
" All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously."
So `WarehouseCalloutServiceTest.execute` will be ran at the moment of `Test.stopTest()` because `System.schedule` is wrapped in startTest/stopTest.
`WarehouseCalloutService` will be enqueued but `WarehouseCalloutService.execute` will be never ran because `System.enqueueJob` is not wrapped in startTest/stopTest.
So any Asserts will be passed.
What is wrong?
Regards,
Alexander