Newer Version Available

This content describes an older version of this product. View Latest

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. Click Develop | Static Resources, and then New Static Resource.
    2. Name your static resource.
    3. Choose the file to upload.
    4. 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.

1swfobject.registerObject("clippy.codeblock-0", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
18mock.setStaticResource('myStaticResourceName');
19mock.setStatusCode(200);
20mock.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.

1swfobject.registerObject("clippy.codeblock-1", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17Test.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.

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.

Note

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.

1swfobject.registerObject("clippy.codeblock-2", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class CalloutStaticClass {
18    public static HttpResponse getInfoFromExternalService(String endpoint) {
19        HttpRequest req = new HttpRequest();
20        req.setEndpoint(endpoint);
21        req.setMethod('GET');
22        Http h = new Http();
23        HttpResponse res = h.send(req);
24        return res;
25    }
26}
1swfobject.registerObject("clippy.codeblock-3", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@isTest
18private class CalloutStaticClassTest {
19    @isTest static void testCalloutWithStaticResources() {
20        // Use StaticResourceCalloutMock built-in class to
21        // specify fake response and include response body 
22        // in a static resource.
23        StaticResourceCalloutMock mock = new StaticResourceCalloutMock();
24        mock.setStaticResource('mockResponse');
25        mock.setStatusCode(200);
26        mock.setHeader('Content-Type', 'application/json');
27        
28        // Set the mock callout mode
29        Test.setMock(HttpCalloutMock.class, mock);
30        
31        // Call the method that performs the callout
32        HTTPResponse res = CalloutStaticClass.getInfoFromExternalService(
33            'http://api.salesforce.com/foo/bar');
34        
35        // Verify response received contains values returned by
36        // the mock response.
37        // This is the content of the static resource.
38        System.assertEquals('{"hah":"fooled you"}', res.getBody());
39        System.assertEquals(200,res.getStatusCode());
40        System.assertEquals('application/json', res.getHeader('Content-Type'));   
41    }
42}

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.

1swfobject.registerObject("clippy.codeblock-4", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17MultiStaticResourceCalloutMock multimock = new MultiStaticResourceCalloutMock();
18multimock.setStaticResource('http://api.salesforce.com/foo/bar', 'mockResponse');
19multimock.setStaticResource('http://api.salesforce.com/foo/sfdc', 'mockResponse2');
20multimock.setStatusCode(200);
21multimock.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.

1swfobject.registerObject("clippy.codeblock-5", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17Test.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.

1swfobject.registerObject("clippy.codeblock-6", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class CalloutMultiStaticClass {
18    public static HttpResponse getInfoFromExternalService(String endpoint) {
19        HttpRequest req = new HttpRequest();
20        req.setEndpoint(endpoint);
21        req.setMethod('GET');
22        Http h = new Http();
23        HttpResponse res = h.send(req);
24        return res;
25    }
26}
1swfobject.registerObject("clippy.codeblock-7", "9");
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@isTest
18private class CalloutMultiStaticClassTest {
19    @isTest static void testCalloutWithMultipleStaticResources() {
20        // Use MultiStaticResourceCalloutMock to
21        // specify fake response for a certain endpoint and 
22        // include response body in a static resource.    
23        MultiStaticResourceCalloutMock multimock = new MultiStaticResourceCalloutMock();
24        multimock.setStaticResource(
25            'http://api.salesforce.com/foo/bar', 'mockResponse');
26        multimock.setStaticResource(
27            'http://api.salesforce.com/foo/sfdc', 'mockResponse2');
28        multimock.setStatusCode(200);
29        multimock.setHeader('Content-Type', 'application/json');
30        
31        // Set the mock callout mode
32        Test.setMock(HttpCalloutMock.class, multimock);
33        
34        // Call the method for the first endpoint
35        HTTPResponse res = CalloutMultiStaticClass.getInfoFromExternalService(
36            'http://api.salesforce.com/foo/bar');
37        // Verify response received 
38        System.assertEquals('{"hah":"fooled you"}', res.getBody());
39        
40        // Call the method for the second endpoint
41        HTTPResponse res2 = CalloutMultiStaticClass.getInfoFromExternalService(
42            'http://api.salesforce.com/foo/sfdc');
43        // Verify response received 
44        System.assertEquals('{"hah":"fooled you twice"}', res2.getBody());
45    }
46}