Pages

Tuesday, January 3, 2017

Apex Integration Services "Apex REST Callouts"

Create an Apex class that calls a REST endpoint and write a test class.

To pass this challenge, create an Apex class that calls a REST endpoint to return the name of an animal, write unit tests that achieve 100% code coverage for the class using a mock response, and run your Apex tests.
  • The Apex class must be called 'AnimalLocator', have a 'getAnimalNameById' method that accepts an Integer and returns a String.
  • The 'getAnimalNameById' method must call https://th-apex-http-callout.herokuapp.com/animals/:id, using the ID passed into the method. The method returns the value of the 'name' property (i.e., the animal name).
  • Create a test class named AnimalLocatorTest that uses a mock class called AnimalLocatorMock to mock the callout response.
  • The unit tests must cover all lines of code included in the AnimalLocator class, resulting in 100% code coverage.
  • Run your test class at least once (via 'Run All' tests the Developer Console) before attempting to verify this challenge.
AnimalLocator Class with getAnimalNameById method:

public class AnimalLocator
{
  public static String getAnimalNameById(Integer id){
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+id);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
          String strResp = '';
           system.debug('******response '+response.getStatusCode());
           system.debug('******response '+response.getBody());
        // If the request is successful, parse the JSON response.
        if (response.getStatusCode() == 200) 
        {
            // Deserializes the JSON string into collections of primitive data types.
           Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            // Cast the values in the 'animals' key as a list
           Map<string,object> animals = (map<string,object>) results.get('animal');
            System.debug('Received the following animals:' + animals );
            strResp = string.valueof(animals.get('name'));
            System.debug('strResp >>>>>>' + strResp );
        }
        return strResp ;
   }
  
}

Mock Callout Response : AnimalLocatorMock

@isTest
global class AnimalLocatorMock implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest request) {
        HttpResponse response = new HttpResponse ();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"animal":{"id":1,"name":"chicken","eats":"chiken food","says":"cluck cluck"}}');
        response.setStatusCode(200);
        return response;
    }

}

AnimalLocatorTest Class:
@isTest
private class AnimalLocatorTest {
    @isTest static void AnimalLocatorMock1(){
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
        string result = AnimalLocator.getAnimalNameById(1);
        string expectedResult = 'chicken';
        System.assertEquals(result, expectedResult);
    }

} 

9 comments:

  1. Thanks for the solution Ankit! Really helpful.

    ReplyDelete
  2. I really enjoyed while reading your article and it is good to know the latest updates. Do post more. Please also read my topics about

    Salesforce Products
    Salesforce Consultant
    Salesforce Integration Service

    ReplyDelete
  3. the thing is, it says on the article (are we looking a the same? https://trailhead.salesforce.com/content/learn/modules/apex_integration_services/apex_integration_rest_callouts) we must use the JSON in https://th-apex-http-callout.herokuapp.com/animals/, where we supply an integer ID. And in that URL, is a list of strings (the names). But your code tests a string with a single object, retrieving the name: it never uses the URL! how can it work? Problem is, it does...

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. means that method's getAnimalNameById parameter is not being used. it get the element with results.get('animal');

    for that to work, JSON needs another structure:

    {"animal":{
    "id":1,"name":"chicken","eats":"chiken food","says":"cluck cluck"}
    "id":2,"name":"pesky porcupine","eats":"chiken food","says":"GRRAAAAA!"}
    "id":3,"name":"hungry hippo","eats":"herbs","says":"grrrr"}
    "id":4,"name":"squeaky squirrel","eats":"nuts","says":"hi hi"},
    }

    ReplyDelete
  6. Thanks for sharing this informative article on Apex Integration Services "Apex REST Callouts" If you want to Salesforce Services for your project. Please visit us.

    ReplyDelete