Introduction
This tutorial assumes that you already know what a Callout is, and are familiarized with terms like: endpoint, Restful services, SOAP and http requests operations (get, post, put and delete). In conclusion, we are going to show you how to make an http request with Salesforce to consume a web service, and how to test it.
Making a Callout
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
private HttpResponse makeRequest(String url, String method) { // Instantiate a new http object HttpResponse res; Http h = new Http(); // Instantiate a new HTTP request, specify the method as well as the endpoint HttpRequest req = new HttpRequest(); try { req.setEndpoint(url); req.setMethod(method); // Send the request, and return a response res = h.send(req); } catch(System.CalloutException e) { System.debug(e.getStackTraceString()); } return res; } |
The “url” parameter is the endpoint that we want to hit to consume the web service and the “method” is the operation that we want to execute: “GET”, “DELETE”, “POST” or “PUT”.
So, we could call this method like this:
1 2 |
String url = 'https://graph.facebook.com/v2.8/me/friends?access_token=' + userAccessToken; response = makeRequest(url, 'GET'); |
The response will contain a JSON that we need to parse in order to get the required data.
What about testing?
Basically, what we need to do is to construct a fake response (maybe JSON) and when the test method runs, we are going to get that response from the method we are testing or, maybe, some data that we are expecting in our test method. To explain this, let’s keep things simple and say that the method that we need to test retrieves the http response (JSON in this case).
So, how to create a fake response for testing purposes?
Just make a class that implements HttpCalloutMock:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
public with sharing class FacebookRequestMock implements HttpCalloutMock { private Integer code; private String status; private Blob bodyAsBlob; private Map<String, String> headers; private HttpResponse response; public FacebookRequestMock(HttpResponse response) { this.response = response; } /** * Class constructor * * @param code The fake message code. * @param status The fake message status. * @param body The fake message body. * @param headers The contents of the response header. */ public FacebookRequestMock(Integer code, String status, String body, Map<String, String> headers) { this.code = code; this.status = status; this.bodyAsBlob = Blob.valueOf(body); this.headers = headers; } /** * Set a fake HttpResponse message for call out on test methods * * @param req HTTP request made it on test method. * @return HTTP fake response */ public HTTPResponse respond(HTTPRequest req) { if (response == null) { response = new HttpResponse(); response.setStatusCode(code); response.setStatus(status); response.setBodyAsBlob(bodyAsBlob); if (headers != null) { for (String key : headers.keySet()) { response.setHeader(key, headers.get(key)); } } } return response; } } |
As you can see the class has 2 constructors, one of them takes an HttpResponse so, what we can do in our test method is to create an instance of this class (FacebokRequestMock, for example, it can be whatever). Then, when the test method gets the response, it will be what we send by parameters to the FacebookRequestMock constructor. Let’s see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/** * Tests the app's facebook dashboard. Things like: list of friends, profile picture, etc... * */ @isTest public with sharing class TestFacebookDashboardController { static testMethod void testGetFriends() { FacebookDashboardController fdc = new FacebookDashboardController(); // Create a fake response for user's friends HttpResponse responseFriends = new HttpResponse(); String body = '{"data":[{"name":"Test User","id":"us3r1d"}],' + '"paging":{"cursors":{"before":"73s7Before' + '73s7Before","after":"73s7After' + '73s7After"}},"summary":{"total_count":1}}'; responseFriends.setStatusCode(200); responseFriends.setStatus('OK'); responseFriends.setBody(body); Test.startTest(); Test.setMock(HttpCalloutMock.class, new FacebookRequestMock(responseFriends)); fdc.userAccessToken = 'us3r70k3n'; fdc.getFriends(); Test.stopTest(); System.Assert(fdc.friends != null && !fdc.friends.isEmpty()); } } |
Take a look at lines: 12-19, we are creating the fake JSON response and with Test.setMock we are setting that fake response to our Mock class. In this way, when the method that we need to test is executed, it’s going to retrieve that fake response.
Looks like we have all we need to implement and test an HTTP Callout in Salesforce. Let’s do it! Happy coding!