Testing HTTP Callouts Using Static Resources

You can test HTTP callouts by specifying the body of the response you’d like to receive in a static resource and using one of two built-in classes—StaticResourceCalloutMock or MultiStaticResourceCalloutMock.

Testing HTTP Callouts Using StaticResourceCalloutMock

Apex provides the built-in StaticResourceCalloutMock class that you can use to test callouts by specifying the response body in a static resource. When using this class, you don’t have to provide your own implementation of the HttpCalloutMock interface. Instead, just create an instance of StaticResourceCalloutMock and set the static resource to use for the response body, along with other response properties, like the status code and content type.

First, you must create a static resource from a text file to contain the response body:
  1. Create a text file that contains the response body to return. The response body can be an arbitrary string, but it must match the content type, if specified. For example, if your response has no content type specified, the file can include the arbitrary string abc. If you specify a content type of application/json for the response, the file content should be a JSON string, such as {"hah":"fooled you"}.
  2. Create a static resource for the text file:
    1. From Setup, enter Static Resources in the Quick Find box, then select Static Resources.
    2. Click New.
    3. Name your static resource.
    4. Choose the file to upload.
    5. Click Save.

To learn more about static resources, see “Defining Static Resources” in the Salesforce online help.

Next, create an instance of StaticResourceCalloutMock and set the static resource, and any other properties.

StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
mock.setStaticResource('myStaticResourceName');
mock.setStatusCode(200);
mock.setHeader('Content-Type', 'application/json');

In your test method, call Test.setMock to set the mock callout mode and pass it HttpCalloutMock.class as the first argument, and the variable name that you created for StaticResourceCalloutMock as the second argument.

Test.setMock(HttpCalloutMock.class, mock);

After this point, if your test method performs a callout, the callout is not made and the Apex runtime sends the mock response you specified in your instance of StaticResourceCalloutMock.

Note

Note

If the code that performs the callout is in a managed package, you must call Test.setMock from a test method in the same package with the same namespace to mock the callout.

This is a full example containing the test method (testCalloutWithStaticResources) and the method it is testing (getInfoFromExternalService) that performs the callout. Before running this example, create a static resource named mockResponse based on a text file with the content {"hah":"fooled you"}. Save each class separately and run the test in CalloutStaticClassTest.

public class CalloutStaticClass {
    public static HttpResponse getInfoFromExternalService(String endpoint) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        return res;
    }
}
@isTest
private class CalloutStaticClassTest {
    @isTest static void testCalloutWithStaticResources() {
        // Use StaticResourceCalloutMock built-in class to
        // specify fake response and include response body 
        // in a static resource.
        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
        mock.setStaticResource('mockResponse');
        mock.setStatusCode(200);
        mock.setHeader('Content-Type', 'application/json');
        
        // Set the mock callout mode
        Test.setMock(HttpCalloutMock.class, mock);
        
        // Call the method that performs the callout
        HTTPResponse res = CalloutStaticClass.getInfoFromExternalService(
            'http://api.salesforce.com/foo/bar');
        
        // Verify response received contains values returned by
        // the mock response.
        // This is the content of the static resource.
        System.assertEquals('{"hah":"fooled you"}', res.getBody());
        System.assertEquals(200,res.getStatusCode());
        System.assertEquals('application/json', res.getHeader('Content-Type'));   
    }
}

Testing HTTP Callouts Using MultiStaticResourceCalloutMock

Apex provides the built-in MultiStaticResourceCalloutMock class that you can use to test callouts by specifying the response body in a static resource for each endpoint. This class is similar to StaticResourceCalloutMock except that it allows you to specify multiple response bodies. When using this class, you don’t have to provide your own implementation of the HttpCalloutMock interface. Instead, just create an instance of MultiStaticResourceCalloutMock and set the static resource to use per endpoint. You can also set other response properties like the status code and content type.

First, you must create a static resource from a text file to contain the response body. See the procedure outlined in Testing HTTP Callouts Using StaticResourceCalloutMock.

Next, create an instance of MultiStaticResourceCalloutMock and set the static resource, and any other properties.

MultiStaticResourceCalloutMock multimock = new MultiStaticResourceCalloutMock();
multimock.setStaticResource('http://api.salesforce.com/foo/bar', 'mockResponse');
multimock.setStaticResource('http://api.salesforce.com/foo/sfdc', 'mockResponse2');
multimock.setStatusCode(200);
multimock.setHeader('Content-Type', 'application/json');

In your test method, call Test.setMock to set the mock callout mode and pass it HttpCalloutMock.class as the first argument, and the variable name that you created for MultiStaticResourceCalloutMock as the second argument.

Test.setMock(HttpCalloutMock.class, multimock);

After this point, if your test method performs an HTTP callout to one of the endpoints http://api.salesforce.com/foo/bar or http://api.salesforce.com/foo/sfdc, the callout is not made and the Apex runtime sends the corresponding mock response you specified in your instance of MultiStaticResourceCalloutMock.

This is a full example containing the test method (testCalloutWithMultipleStaticResources) and the method it is testing (getInfoFromExternalService) that performs the callout. Before running this example, create a static resource named mockResponse based on a text file with the content {"hah":"fooled you"} and another named mockResponse2 based on a text file with the content {"hah":"fooled you twice"}. Save each class separately and run the test in CalloutMultiStaticClassTest.

public class CalloutMultiStaticClass {
    public static HttpResponse getInfoFromExternalService(String endpoint) {
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        return res;
    }
}
@isTest
private class CalloutMultiStaticClassTest {
    @isTest static void testCalloutWithMultipleStaticResources() {
        // Use MultiStaticResourceCalloutMock to
        // specify fake response for a certain endpoint and 
        // include response body in a static resource.    
        MultiStaticResourceCalloutMock multimock = new MultiStaticResourceCalloutMock();
        multimock.setStaticResource(
            'http://api.salesforce.com/foo/bar', 'mockResponse');
        multimock.setStaticResource(
            'http://api.salesforce.com/foo/sfdc', 'mockResponse2');
        multimock.setStatusCode(200);
        multimock.setHeader('Content-Type', 'application/json');
        
        // Set the mock callout mode
        Test.setMock(HttpCalloutMock.class, multimock);
        
        // Call the method for the first endpoint
        HTTPResponse res = CalloutMultiStaticClass.getInfoFromExternalService(
            'http://api.salesforce.com/foo/bar');
        // Verify response received 
        System.assertEquals('{"hah":"fooled you"}', res.getBody());
        
        // Call the method for the second endpoint
        HTTPResponse res2 = CalloutMultiStaticClass.getInfoFromExternalService(
            'http://api.salesforce.com/foo/sfdc');
        // Verify response received 
        System.assertEquals('{"hah":"fooled you twice"}', res2.getBody());
    }
}
Previous
Next