The Winter ’13 release added a couple of new features for testing Apex callouts. Specifically, developers can now either
- Use a Static Resource to save the test response (e.g. a JSON text file) and then use the StaticResourceCalloutMock or MultiStaticResourceCalloutMock system classes to test one or more callouts, or
- Implement one of two new interfaces: HttpCalloutMock, for HTTP (REST) callouts, or WebServiceMock, for Web Service (SOAP) callouts
Pat wrote an excellent blog post breaking down the first option. Lets review the second option, specifically how to implement the HttpCalloutMock interface to test HTTP callouts.
Testing a single HTTP callout
Lets start with a relatively simple requirement of testing an Apex class that makes a single HTTP (i.e. REST) callout. Here’s the code that we need to test.
The first step is to create a class that implement the HttpCalloutMock interface.
Note: While it is not required to mark your HttpCalloutMock implementation class as @isTest, it is generally a best practice to do so in order to exclude the class from your organization’s code size limit of 3 MB.
You need to implement the ‘respond’ method of the HttpCalloutMock interface in which you return a fake HttpResponse. As you can see, we’ve created a utility testing class that can be used to test any scenario that involves a single HTTP callout, and not just the CalloutAccounts class shown earlier. This utility class can be used to test both binary and String responses (depending on which constructor you use to instantiate the class) and also lets you specify the HTTP code and status for the fake response. You can optionally also specify HTTP headers to be included in the fake response. Next, lets see how we use this HttpCalloutMock implementation to test our CalloutAccounts class.
Line 8 shows how we use the Test.setMock system method to tell the platform which HttpCalloutMock implementation to use during the test. After that line, if an HTTP callout is invoked in test context (e.g. the callout code in our CalloutAccounts.getAccounts method), the callout is not made and you receive the mock response specified in the ‘respond’ method implementation.