You can use the ExternalServiceTest method to
mock callback and asynchronous responses.
Required Editions
| Available in: Lightning Experience |
| Available in: Enterprise, Performance, Unlimited, and Developer Editions |
The code examples in this topic are based on the fictitious schema in Example API Specification With Callback Operation.
This snippet shows an example unit test for the Acme Mortgage service. To test external services with callbacks in Apex, the Acme Mortgage callout mock class mocks the submit-mortgage application request and asserts the expected request payload. The test class triggers the mocked external service’s callback response through an instance of test External Service methods.
global class AcmeMortgageHttpCalloutMock implements HttpCalloutMock {
private String callbackUrl;
// Mock asynchronous response
public void callBack() {
HttpRequest request = new HttpRequest();
request.setEndpoint(callbackUrl);
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json');
request.setBody('{' +
'"applicationNumber": "900-X",' +
'"status": "Approved",' +
'"approvedAmount": 10000' +
'}');
HttpResponse response = Test.getExternalService().sendCallback(request);
Assert.areEqual(200, response.getStatusCode());
}
// Mock initial response
global HttpResponse respond(HttpRequest request) {
if (request.getMethod().equals('POST') && request.getEndpoint().equals('callout:AcmeMortgageCredential/applications')) {
return respondSubmitApplication(request);
}
...
System.assert(false, 'Request method and/or endpoint not valid: ' + request.getMethod() + ' ' + request.getEndpoint());
return null;
}
private HttpResponse respondSubmitApplication(HttpRequest request) {
// Retrieve the callback URL from request
ExternalService.AcmeMortgage_SubmitApplication_IN_Body body =
(ExternalService.AcmeMortgage_SubmitApplication_IN_Body)
Json.deserialize(request.getBody(),
(ExternalService.AcmeMortgage_SubmitApplication_IN_Body.class);
callbackUrl = body.callbackUrlForOutcomes.approved;
HttpResponse response = new HttpResponse();
response.setHeader('Content-Type', 'application/json');
response.setBody('{"applicationNumber": "900-X"}');
response.setStatusCode(201);
return response;
}
}
The test class sets up the callout mock, sends the mortgage application request, and then mocks the callback with the mortgage application outcome:
@IsTest
public class AcmeMortgageApplicationTest {
@IsTest
static void testSubmitApplicationWithApprovalCallback() {
AcmeMortgageHttpCalloutMock calloutMock = new AcmeMortgageHttpCalloutMock();
Test.setMock(HttpCalloutMock.class, calloutMock);
Test.startTest();
ExternalService.AcmeMortgage acme = new ...();
...acme.SubmitApplication(...);
// Call back with mock responses
calloutMock.callBack();
// Send all registered callback
Test.stopTest();
// Assert expected end result - e.g approved mortgage object created
...
}
}