Testing Integrations
By the end of this lesson, you'll be able to:
- Apply Module 31's HttpCalloutMock to test a real integration built in this module
- Test both a successful and a failed external response
- Recognize this as the closing loop this module has been building toward
Prerequisites: "Platform Events"
The service being tested
public class ShippingRateService {
public Decimal getRate(String postalCode) {
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:Shipping_API/rates?postal=' + postalCode);
request.setMethod('GET');
HttpResponse response = new Http().send(request);
if (response.getStatusCode() != 200) {
throw new CalloutException('Shipping API returned status ' + response.getStatusCode());
}
Map<String, Object> parsed = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
return (Decimal) parsed.get('rate');
}
}
This combines nearly every lesson from this module: a Named Credential endpoint (Lesson 5), an HttpRequest/HttpResponse callout (Lesson 4), and JSON parsing (Lesson 2) — a genuinely realistic integration, ready to test.
Testing the success path
@isTest
public class ShippingRateMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest request) {
HttpResponse response = new HttpResponse();
response.setStatusCode(200);
response.setBody('{"rate": 45.50}');
return response;
}
}
@isTest
private class ShippingRateServiceTest {
@isTest
static void getRateReturnsParsedValue() {
Test.setMock(HttpCalloutMock.class, new ShippingRateMock());
Test.startTest();
Decimal rate = new ShippingRateService().getRate('8001');
Test.stopTest();
System.assertEquals(45.50, rate);
}
}
This is exactly Module 31's "Mocking HTTP Callouts" lesson, now testing genuinely real integration logic instead of an isolated example — the mock, the assertion, and the specific-value habit from Module 31 all directly applied.
Testing the failure path
@isTest
public class ShippingRateFailureMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest request) {
HttpResponse response = new HttpResponse();
response.setStatusCode(500);
response.setBody('Internal Server Error');
return response;
}
}
@isTest
static void getRateThrowsOnServerError() {
Test.setMock(HttpCalloutMock.class, new ShippingRateFailureMock());
try {
new ShippingRateService().getRate('8001');
System.assert(false, 'Expected a CalloutException');
} catch (CalloutException e) {
System.assert(e.getMessage().contains('500'));
}
}
This is Module 31's exception-testing pattern (the try/System.assert(false)/catch shape) combined with Module 31's failure-mock pattern — confirming the throw new CalloutException(...) guard in getRate actually fires correctly on a real 500 response.
Exercise
Write a mock class returning a 404 status, and a test confirming getRate throws a CalloutException containing "404" for that response.
Show hint
Follow the same pattern as the 500 mock and test in this lesson.
Testing Integrations Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
This closing lesson connects every earlier lesson back to Module 31's HttpCalloutMock — testing a real callout, a real JSON parse, and a real error-handling path, all together.