+ Start a Discussion
VamsiVamsi 

apex rest callouts challenge unable to complete

Hi,

I have written a test class for this rest callouts but its not covering 100% code coverage. Can someone please help me

It throws me error when I run the test class 
Class.AnimalLocator.getAnimalNameById: line 16, column 1 Class.AnimalLocatorTest.testcallout: line 7, column 1

Apex class 

public class AnimalLocator {

public static string getAnimalNameById (integer i)
{
    string a;
    Http ht = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + i);
        request.setMethod('GET');
        HttpResponse response = ht.send(request);
        // If the request is successful, parse the JSON response.
    if (response.getStatusCode() == 200) 
    {
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
             Map<string,object> cc = (Map<string,object>) result.get('animals');
        a = (string)cc.get('name');
    }
    return a;
  }
}


Test class

@isTest
public class AnimalLocatorTest 
{
@isTest static void testcallout()
{
      Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock()); 
    string response = AnimalLocator.getAnimalNameById (2); 
String expectedValue = '{"animal":{"id":2,"name":"bear","eats","berries, campers, adam seligman","says":"yum yum"}}'; 
system.assertEquals('eats', response);
   
   }
}

@isTest
global class AnimalLocatorMock implements HttpCalloutMock 
{
global HTTPResponse respond(HTTPRequest request) 
{
        // Create a fake response
         HttpResponse response = new HttpResponse(); 
     response.setHeader('Content-Type', 'application/json');
    response.setBody('{"animal":{"i":2,"name":"bear","eats":"berries, campers, adam seligman","says":"yum yum"}}'); 
        response.setStatusCode(200);
        return response;
}
}
 
Best Answer chosen by Vamsi
Akhil MehraAkhil Mehra
hi guys ,
I have written a test class for this rest callouts with 100% code coverage

class Code:
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 ;
   }
  
}

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



@isTest
private class AnimalLocatorTest {

    @isTest static  void testGetAnimalNameById() {
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock()); 
        String result = AnimalLocator.getAnimalNameById(1);
        System.assertEquals(result, 'chicken');
    }
}
 

All Answers

praveen sonepraveen sone
what is the error message you see? please post that as well.
VamsiVamsi
Sorry I forgot to mention 

It throws : System.NullPointerException: Attempt to de-reference a null object
Amit Chaudhary 8Amit Chaudhary 8
Please check below post. I hope that will help you

 
@IsTest
private class AnimalLocatorTest {
    @isTest static  void  testGetCallout() {
    // Set mock callout class
    Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
    // This causes a fake response to be sent
    // from the class that implements HttpCalloutMock.
    String animalname = AnimalLocator.getAnimalNameById(2);
    // Verify that the response received contains fake values        
    String expectedValue = 'bear';
    System.assertEquals(animalname, expectedValue);
    }
}

@IsTest
global class AnimalLocatorMock implements HttpCalloutMock {
    //Implement this interface method
    global HTTPResponse respond(HTTPRequest request) {
        // Create a fake response
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"animal":{"id":2,"name":"bear","eats":"berries, campers, adam seligman","says":"yum yum"}}');
        response.setStatusCode(200);
        return response;
    }
}


 
praveen sonepraveen sone
I think it would still show the exception. I tried this in my own org and din work out.

But, with my original code... I am facing this error

Error: System.JSONException: Unexpected character (':' (code 58)): was expecting comma to separate ARRAY entries at [line:1, column:18]

Code:

Baseclass:

/*public class AnimalLocator{
    public static String getAnimalNameById(Integer id){
        string animalname;
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+ id);
        req.setMethod('GET');

        HttpResponse res = http.send(req);
        if(res.getStatusCode() == 200){    
            Map<String,Object> results = (Map<String,Object>) Json.deserializeUntyped(res.getBody());
            Map<String,Object> animals = (Map<String,Object>) results.get('animals');
            animalname= (String) animals.get('name');
        }        
    return animalname;
    }
} */

Test:

/*
 * @isTest
public class AnimalLocatorTest {
    @isTest static void testGetCallout(){    

        Test.setmock(HttpCalloutMock.class,new AnimalLocatorMock());

        String result = AnimalLocator.getAnimalNameById(0);
        System.assertEquals('majestic',result);
        //System.assertNOTEquals('majestic badger', result,'yes,its wrong');
    }
} */

Mock:

/*
 * @isTest
global class AnimalLocatorMock implements HttpCalloutMock{
    global HttpResponse respond(HttpRequest request){
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-type', 'application/json');
        response.setBody('{"animals":["id":"0","name":"majestic"]}');
        response.setStatusCode(200);
        response.setStatus('success');
        return response;
    }
} */
VamsiVamsi
Hi Amith,

I tried with your code and it shows me the same error : System.NullPointerException: Attempt to de-reference a null object
 
Akhil MehraAkhil Mehra
hi guys ,
I have written a test class for this rest callouts with 100% code coverage

class Code:
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 ;
   }
  
}

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



@isTest
private class AnimalLocatorTest {

    @isTest static  void testGetAnimalNameById() {
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock()); 
        String result = AnimalLocator.getAnimalNameById(1);
        System.assertEquals(result, 'chicken');
    }
}
 
This was selected as the best answer
Bill KratochvilBill Kratochvil
If you consume the service using the following: https://th-apex-http-callout.herokuapp.com/animals you will see 'animals' (plural)

   {"animals":["majestic badger","fluffy bunny","scary bear","chicken"]}

However, once you use a parameter, e.g., https://th-apex-http-callout.herokuapp.com/animals/1 you will get an 'animal' (singular)

    {"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}

Which would require => Map<String,Object> animals = (Map<String,Object>) results.get('animals');   
                      to be => Map<String,Object> animals = (Map<String,Object>) results.get('animal');   
 
Kiran PandiyanKiran Pandiyan
I saw two issues not sure of them. Try and let me know 
public class AnimalLocator {

public static string getAnimalNameById (integer i)
{
    string a;
    Http ht = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + i);
        request.setMethod('GET');
        HttpResponse response = ht.send(request);
        // If the request is successful, parse the JSON response.
    if (response.getStatusCode() == 200) 
    {
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
            Map<string,object> cc = (Map<string,object>) result.get('animal');
            //here i changed animals to animal because there is only animal attribute in the link given
        a = (string)cc.get('name');
    }
    return a;
  }
}


Test class

@isTest
public class AnimalLocatorTest 
{
@isTest static void testcallout()
{
      Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock()); 
    string response = AnimalLocator.getAnimalNameById (2); 
String expectedValue = '{"animal":{"id":2,"name":"bear","eats","berries, campers, adam seligman","says":"yum yum"}}'; 
system.assertEquals('bear', response.animal.name);
   //here I have changed to bear and response.animal.name as the response gets all the info and response.animal.name gives the exact animal's      //name
   }
}

@isTest
global class AnimalLocatorMock implements HttpCalloutMock 
{
global HTTPResponse respond(HTTPRequest request) 
{
        // Create a fake response
         HttpResponse response = new HttpResponse(); 
     response.setHeader('Content-Type', 'application/json');
    response.setBody('{"animal":{"i":2,"name":"bear","eats":"berries, campers, adam seligman","says":"yum yum"}}'); 
        response.setStatusCode(200);
        return response;
}
}