+ Start a Discussion
Jun KeJun Ke 

The Apex class does not appear to be calling the REST endpoint using HttpRequest.

Hi All,

I am doing Apex Rest Callouts in Trailhead Apex Integration Service Module.
https://developer.salesforce.com/trailhead/force_com_dev_intermediate/apex_integration_services/apex_integration_rest_callouts

This is AnimalLocator class.
public class AnimalLocator{
    public static String getAnimalNameById(Integer x){
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        
        req.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + x);
        
        req.setMethod('GET');
        
        HttpResponse res = h.send(req);
        Map<String, Object> results = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
        Map<String, Object> animal = (Map<String, Object>) results.get('animal');
        return (String)animal.get('name');
    }
}
However, I was encountered this error when checking challenge.
Challenge Not yet complete... here's what's wrong: 
The Apex class does not appear to be calling the REST endpoint using HttpRequest.
I have no idea what it means, but I have call the REST endpoint.
Best Answer chosen by Jun Ke
Jeff DouglasJeff Douglas
Steven,

You are doing everything correctly. There's a stupid issue that I've corrected. In the meantime, if you change line #3 in AnimalLocatior to the following (plus an other dependent code) it will work:
 
Http http = new Http();

Thanks

Jeff Douglas
Trailhead Developer Advocate
 

All Answers

Pankaj_GanwaniPankaj_Ganwani
Hi,

Please ensure your end point url should be stored in remote site settings of the org which you have connected with Trailhead.

https://th-apex-http-callout.herokuapp.com
Jun KeJun Ke
Hi Pankaj,

I have added the endpoint to the remote site settings.

And I have executed the code, it returns. It also passed the test execution.
Jeff DouglasJeff Douglas
Steven,

You are doing everything correctly. There's a stupid issue that I've corrected. In the meantime, if you change line #3 in AnimalLocatior to the following (plus an other dependent code) it will work:
 
Http http = new Http();

Thanks

Jeff Douglas
Trailhead Developer Advocate
 
This was selected as the best answer
Jeff DouglasJeff Douglas
Gale, I think I answered this in another thread... https://developer.salesforce.com/forums?communityId=09aF00000004HMGIA2#!/feedtype=SINGLE_QUESTION_DETAIL&dc=Trailhead&criteria=ALLQUESTIONS&id=906F0000000MJADIA4
Mohsin.RazaMohsin.Raza
Jeff, I am having the same issue as Gale and I am not sure what's wrong. Here is my code for the TestClass and HttpCalloutMock 
 
@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 testGetCallout() {
        // Set mock callout class 
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock ()); 
        string animal_name = AnimalLocator.getAnimalNameById(1);
        String expectedValue = 'chicken';
        System.assertEquals(animal_name, expectedValue);
    }
}
Jeff DouglasJeff Douglas
Mohsin,

Try changing line #6 in your code to the correct answer chosen (in green) by Steven Ke. That should do the trick.

Jeff Douglas
Trailhead Developer Advocate
Mohsin.RazaMohsin.Raza
Hi Jeff,

I am not sure how that would work. You are asking me to replace HttpResponse response = new HttpResponse(); with Http http = new Http();

Anyways I still tried that and as expected it did not allow me to save the change because the code is expecting an object of type HttpResponse and not of type Http.

Mohsin
Bruce StewartBruce Stewart
@Mohsin.Raza - did you figure it out / get the test class working?
I'm having trouble as well (first due to a namespace in my Dev org), then similar to above.
Could it be that your expected value is asserting only 1 item "Chicken" while the response comes back with id, name, eats ... ?
Mohsin.RazaMohsin.Raza
@bruce - no I haven't been able to resolve this yet. I dont think the problem is with expected and actual values. The value being returned by AnimalLocator.getAnimalNameById(1) is indeed chicken. This function returns the animal name and not the whole JSON object.

@Jeff, what do you think is the problem here?
Yash GandhiYash Gandhi
Mohsin,
Try removing the space between 'AnimalLocatorMock' and the brackets() in line 18 of your code above. That did the trick for me. So basically  you should have 
Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
instead of
Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock ());

Thanks
Yash

 
Mohsin.RazaMohsin.Raza
Thanks Yash. That worked like a charm.
bhaskar anumlabhaskar anumla
Dear Mohsin,

I am gettiing unexcepted token @ ----- at second isTest line,
please resolve...,
 
Mohsin.RazaMohsin.Raza
Hi Bhaskar, can you please post your code here so that I can try and see what the issue is?
Dhinesh MuralidharanDhinesh Muralidharan
Hi Guys, 
   I am new and i have been trying this challenge. I understand since it is going to be only one object that is returned by through the body of response. the OP has used "Map<String, Object> animal = (Map<String, Object>) results.get('animal');" 

I am wondering like in the tutorial, if we use the List Map instead of just Map. will we get the same result. i tried it but it threw an error saying attempting to de reference a null object. can anyone give clarification on this.
venugopal kapavenugopal kapa
@Mohsin

I have a similar test class but iam getting an Error message 
 unexcepted token:@ at 14th line
 
Akshata Asukar 10Akshata Asukar 10
Below is the code of my Callout class, mock class and  test class, I am getting the error, "Challenge Not yet complete... here's what's wrong: 
The Apex test class 'AnimalLocatorTest' does not appear to be using the AnimalLocatorMock class correctly."

Callout Class
global class AnimalLocator
{
    public class Animal {
    public Integer id;
    public String name;
    public String eats;
    public String says;

    }
    
    public class AnimalResult {
    public Animal animal;
    }

    public Static String getAnimalNameById(integer id)
    {
        List<Object> animal;
        String returnValue ;
        AnimalResult result;
        Http http=new Http();
        HttpRequest request =new HttpRequest();
        request.setEndPoint('https://th-apex-http-callout.herokuapp.com/animals/'+id);
        request.setMethod('GET');
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        //request.setBody('{"id":"'+id+'"}');
        HttpResponse response= http.send(request);
        if(response.getStatusCode()==200)
        {
       result = (AnimalResult) JSON.deserialize(response.getBody(), AnimalResult.class);
       }
        return result.animal.name;

    }
    
}

MOCKResponse Class
@isTest
global class AnimalLocatorMock implements HttpCallOutMock
{
    public static HTTPResponse respond(HttpRequest req) 
    {
            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;

    }

}

Test Class

@isTest
public class AnimalLocatorTest 
{
    public static testMethod void mytestMethod()
    {
        Test.SetMock(HttpCallOutMock.class, new  AnimalLocatorMock());
        
         String res= AnimalLocator.getAnimalNameById(1);
       
        
        String expectedValue = 'chicken';
        System.assertEquals(res, expectedValue);
        


    }

}

 
Mohsin.RazaMohsin.Raza
@Akshata

the code where you call the mock class in your test class has an extra space which is causing the issue. try removing that extra space.

Currently your code is:
        Test.SetMock(HttpCallOutMock.class, new  AnimalLocatorMock());

but it should be
        Test.SetMock(HttpCallOutMock.class, new AnimalLocatorMock());

Please try this and let me know if this works or not.
Mohsin.RazaMohsin.Raza
@Dhinesh,

the reason why list<map> wont work is because the JSON response from the HTTPCallout returns a single object instead of an array of object. We use list when we expect array of object being returned by the HTTPCallout. This is the JSON response that we get from the HTTPCallout that we are making in this example.

{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}
Akshata Asukar 10Akshata Asukar 10
@Mohsin,

Thanks , it worked. :)
bhaskar anumlabhaskar anumla
Hello Mohsin,

My main class:-
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);
        List<Object> animals = NULL;
        String returnValue = NULL;
        System.debug('Response Body####'+response.getBody());
        System.debug('Response Code####'+response.getStatusCode());
        // If the respose is successful then JSON deserialize it
        if(response.getStatusCode() == 200){
            Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            animals = (list<Object>) result.get('animals');
            System.debug('animals');
        }
        //if(animals.size()>0 && animals!= NULL && id< animals.size()){
            returnvalue = (String)animals.get(id);
       // }
         return returnvalue;
    }
}

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;
    }
}

My Test 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;
    }
}
 
Harsh DodiyaHarsh Dodiya

Hello,

Error : Challenge Not yet complete... here's what's wrong: 
There was an unexpected error in your org which is preventing this assessment check from completing: System.NullPointerException: Attempt to de-reference a null object

Class : AnimalLocator

public class AnimalLocator {
    public static string getAnimalNameById(Integer x){
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        Map<String, Object>animal= new Map<String,Object>();
        HttpResponse response=http.send(request);
        
        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());
            animal = (Map<String, Object>) results.get('animal');
        }
            return(String)animal.get('name');
    }
}

Class : AnimalLocatorTest

@isTest
private class AnimalLocatorTest{
    @isTest static  void AnimalLocatorMock1() {
        Test.SetMock(HttpCallOutMock.class, new AnimalLocatorMock());
        string result=AnimalLocator.getAnimalNameById(3);
        string expectedResult='chicken';
        System.assertEquals(result, expectedResult);
    }
}

Class : 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":"chicken food","says":"cluck cluck"}}');
        response.setStatusCode(200);
        return response;
    }
}

Can some one help me here please.

Jeff DouglasJeff Douglas
I think the problem is that you are not passing the ID of the animal as part of the endpoint. Try this:
 
request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + x);

Jeff Douglas
Trailhead Developer Advocate

 
Fnu SumitFnu Sumit
HARSH YOU USE AnimalLocatorMock1()  IT SHOULD BE AnimalLocatorMock() 
bhaskar anumlabhaskar anumla
Dear All, above my code is working  is fine.
Just copy and paste run the class, run test class and finally, run all test.
I will work fine.
 
Ashok Kumar NayakAshok Kumar Nayak
Thank You Guyz !!! It worked fine for me.

//Main Class

public class AnimalLocator{

public static string getAnimalNameById(Integer id) {

Http http = new Http();
HttpRequest hreq = new HttpRequest();
hreq.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+id);
hreq.setMethod('GET');
HttpResponse res = http.send(hreq);
Map<String,Object> animals = new Map<String,Object>();

if (res.getStatusCode() == 200) {
Map<String,Object> results = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());
animals = (Map<String,Object>)results.get('animal');
}

else{System.debug('The status code returned was not expected: ' + res.getStatusCode() + ' ' + res.getStatus());}

return (string)animals.get('name');
}
}

************************************************************************************

//Mock Class

@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.setBody('{"animal":{"id":1,"name":"chicken"}}');
        response.setStatusCode(200);
        return response;
    }

}

*******************************************************************************************

//The Test Class

@isTest
private class AnimalLocatorTest{

@isTest static void AnimalsCalloutsTest() {

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

String ALresult = AnimalLocator.getAnimalNameById(1);

String expectedValue = 'chicken';

System.assertEquals(ALresult, expectedValue);


}
}

**********************************************************************************************