Skip to content

Instantly share code, notes, and snippets.

@mannharleen
Created October 31, 2016 15:36
Show Gist options
  • Save mannharleen/2890d40f5cea62d058d62f7c16e39f73 to your computer and use it in GitHub Desktop.
Save mannharleen/2890d40f5cea62d058d62f7c16e39f73 to your computer and use it in GitHub Desktop.
Salesforce trailhead - Apex-Integration-Services-Apex-REST-Callouts
public class AnimalLocator {
public class cls_animal {
public Integer id;
public String name;
public String eats;
public String says;
}
public class JSONOutput{
public cls_animal animal;
//public JSONOutput parse(String json){
//return (JSONOutput) System.JSON.deserialize(json, JSONOutput.class);
//}
}
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.setHeader('id', String.valueof(id)); -- cannot be used in this challenge :)
request.setMethod('GET');
HttpResponse response = http.send(request);
system.debug('response: ' + response.getBody());
//Map<String,Object> map_results = (Map<String,Object>) JSON.deserializeUntyped(response.getBody());
jsonOutput results = (jsonOutput) JSON.deserialize(response.getBody(), jsonOutput.class);
//Object results = (Object) map_results.get('animal');
system.debug('results= ' + results.animal.name);
return(results.animal.name);
}
}
@IsTest
global class AnimalLocatorMock implements HttpCalloutMock {
global HTTPresponse respond(HTTPrequest request) {
Httpresponse response = new Httpresponse();
response.setStatusCode(200);
//-- directly output the JSON, instead of creating a logic
//response.setHeader('key, value)
//Integer id = Integer.valueof(request.getHeader('id'));
//Integer id = 1;
//List<String> lst_body = new List<String> {'majestic badger', 'fluffy bunny'};
//system.debug('animal return value: ' + lst_body[id]);
response.setBody('{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}');
return response;
}
}
@IsTest
public class AnimalLocatorTest {
@isTest
public static void testAnimalLocator() {
Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
//Httpresponse response = AnimalLocator.getAnimalNameById(1);
String s = AnimalLocator.getAnimalNameById(1);
system.debug('string returned: ' + s);
}
}
@Shivrajgithub
Copy link

Shivrajgithub commented Jun 6, 2022

Hello Everyone

I think most of facing similar error with remote site setting - "No Remote Site named ‘animals_soap’ was found with the correct Name, URL, and Description".

I've resolved remote site setting issue

Follow below steps and create two remote site settings. Do NOT forget to add Description.
1)
Click New Remote Site.
For the remote site name, enter animals_http.
For the remote site URL, enter https://th-apex-http-callout.herokuapp.com.
For the description, enter "Trailhead animal service: HTTP".
Click Save & New.

For the second remote site name, enter animals_soap.
For the remote site URL, enter https://th-apex-soap-service.herokuapp.com.
For the description, enter "Trailhead animal service: SOAP".
Click Save.

image

image

image

Hope this help.

@prajwal2021
Copy link

you saved my day, i was literally about to quit then i saw your post , thank you so much

@soninishchal
Copy link

can anyone solve this problem

Challenge not yet complete in Build Travel App
No Remote Site named ‘animals_http’ was found with the correct Name, URL, and Description.

@abdellinux
Copy link

If you still get the error "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." and you have correctly set the remote site settings, that does not mean necessarily that the method does not exist. Check the logs after you click on "Check Challenge" you will have a better understanding of the error you made in your code. In my case, the json i have imagined wasn't the right one so my test class worked just fine with 100 % coverage but the json trailhead was expecting was different.
2023-08-21_20h10_41

@Dilipchitturi
Copy link

If you still get the error "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." and you have correctly set the remote site settings, that does not mean necessarily that the method does not exist. Check the logs after you click on "Check Challenge" you will have a better understanding of the error you made in your code. In my case, the json i have imagined wasn't the right one so my test class worked just fine with 100 % coverage but the json trailhead was expecting was different. 2023-08-21_20h10_41

so whats the solution to it??I cant able to rectify it

@skuhn002
Copy link

skuhn002 commented Sep 17, 2023

I don't have a full explanation, but I want to point out that I got past these issues by setting up a class similar to the original poster's (OP - @mannharleen ) AnimalLocator.cls code. I believe the reason is that I was returning a single string from my mock which didn't include an object representing an animal, just the name.

res.setBody('{"name":"singing squirtle"}');

I hope this helps, and I would really appreciate if someone, possibly OP @mannharleen, could help me understand how I could have achieved the same results without creating an animal class. For reference I'll provide the code where I was attempting to do this so you may be able to just point out what's wrong.

Assume the JSON body looks like this:
{"animals" : {[{ "name" : "test animal" }]} }

Reference Code - (AnimalLocator.apxc):

public class AnimalLocator {
public static String getAnimalNameById(Integer animalId){
Http http = new Http();
HttpRequest req = new HttpRequest();

    req.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + animalId);
    req.setMethod('GET');
    req.setHeader('Content-Type', 'application/json;charset=UTF-8');
    
    HttpResponse res = http.send(req);
    
    Map<String, Object> jRes = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
        
   List<Object> animals = (List<Object>) jRes.get('animals');

    String animalName = (String) animals.name;
    
    return animalName;
}

}

@kazu0221
Copy link

Thank you!

I was able to complete the process by converting the JSON data into the expected format.

@ugkhan21
Copy link

This does the job

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

    Http http = new Http();
    HttpResponse res = http.send(req);
    if (res.getStatusCode() == 200) { 
        Map<String, Object> jRes = (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
        Map<String, Object> animal = (Map<String, Object>) jRes.get('animal');
        String animalName = (String) animal.get('name');
        return animalName;
    } else {
        return null;
    }
}

}
`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment