Newer Version Available

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

Testing Asynchronous Callouts

Write tests to test your controller and meet code coverage requirements for deploying or packaging Apex. Because Apex tests don’t support making callouts, you can simulate callout requests and responses. When you’re simulating a callout, the request doesn’t get sent to the external service, and a mock response is used.

The following example shows how to invoke a mock asynchronous callout in a test for a Web service call that uses HTTPRequest. To simulate callouts in continuations, call these methods of the Test class: Test.setContinuationResponse() and Test.invokeContinuationMethod().

The controller class to test is listed first, followed by the test class. The controller class from Make Long-Running Callouts with Continuations is reused here.

1public with sharing class ContinuationController {
2    // Unique label corresponding to the continuation request
3    public String requestLabel;
4    // Result of callout
5    public String result {get;set;}
6    // Endpoint of long-running service
7    private static final String LONG_RUNNING_SERVICE_URL = 
8        '<Insert your service URL>';
9   
10   // Action method
11    public Object startRequest() {
12      // Create continuation with a timeout
13      Continuation con = new Continuation(40);
14      // Set callback method
15      con.continuationMethod='processResponse';
16      
17      // Create callout request
18      HttpRequest req = new HttpRequest();
19      req.setMethod('GET');
20      req.setEndpoint(LONG_RUNNING_SERVICE_URL);
21      
22      // Add callout request to continuation
23      this.requestLabel = con.addHttpRequest(req);
24      
25      // Return the continuation
26      return con;  
27    }
28    
29    // Callback method 
30    public Object processResponse() {   
31      // Get the response by using the unique label
32      HttpResponse response = Continuation.getResponse(this.requestLabel);
33      // Set the result variable that is displayed on the Visualforce page
34      this.result = response.getBody();
35      
36      // Return null to re-render the original Visualforce page
37      return null;
38    }
39}

This example shows the test class corresponding to the controller. This test class contains a test method for testing an asynchronous callout. In the test method, Test.setContinuationResponse sets a mock response, and Test.invokeContinuationMethod causes the callback method for the continuation to be executed. The test ensures that the callback method processed the mock response by verifying that the controller’s result variable is set to the expected response.

1@isTest
2public class ContinuationTestingForHttpRequest {
3    public static testmethod void testWebService() {
4        ContinuationController controller = new ContinuationController();
5        // Invoke the continuation by calling the action method
6        Continuation conti = (Continuation)controller.startRequest();
7        
8        // Verify that the continuation has the proper requests
9        Map<String, HttpRequest> requests = conti.getRequests();
10        system.assert(requests.size() == 1);
11        system.assert(requests.get(controller.requestLabel) != null);
12        
13        // Perform mock callout 
14        // (i.e. skip the callout and call the callback method)
15        HttpResponse response = new HttpResponse();
16        response.setBody('Mock response body');   
17        // Set the fake response for the continuation     
18        Test.setContinuationResponse(controller.requestLabel, response);
19        // Invoke callback method
20        Object result = Test.invokeContinuationMethod(controller, conti);
21        // result is the return value of the callback
22        System.assertEquals(null, result);
23        // Verify that the controller's result variable
24        //   is set to the mock response.
25        System.assertEquals('Mock response body', controller.result);
26    }
27}