function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ 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;
}
}
Developer One 25Developer One 25
Still Facing the below issue like 

Executing the 'getAnimalNameById' method on 'AnimalLocator' failed. Make sure the method exists with the name 'getAnimalNameById', is public and static, accepts an Integer, and returns a String.

I used the below code to increase the coverage of Class AnimalLocator but now its giving wierd error for method and signature but those are already take care not sure

public class AnimalLocator{

  public static String getAnimalNameById(Integer x){
      
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+x);
        req.setMethod('GET');
        HttpResponse resp = http.send(req);
          String strResp = '';
        if (resp.getStatusCode() == 200) 
        {
           Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(resp.getBody());
           Map<string,object> animals = (map<string,object>) results.get('animal');
           strResp = string.valueof(animals.get('name'));
        }
        return strResp ;
   }
  
}

 

@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":"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');
    }
}