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
Eric Anderson 54Eric Anderson 54 

Missing something on the Animal Locator exercise

I don't know what I am doing wrong. I've been working on the Animal Locator exercise in trailhead having to do with REST API Callouts and just can not get the result I'm working on to pass the 'Challenge'. My code is 100% tested, and it seems to meet all the criteria, but I keep getting the following message: "Challenge Not yet complete... here's what's wrong:
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."

Below is my code:

AnimalLocator.apxc (Class)

public class AnimalLocator {
    public static string getAnimalNameById(integer numSubmitted) {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + numSubmitted);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        string replyName = 'None returned';
        if (response.getStatusCode() == 200) {
         replyName = response.getBody();
        }
            return replyName;
    }
}

AnimalLocatorTest.apxc

@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 = 'Charles H Bones Esquire';
    System.assertEquals(animalname, expectedValue);
    }
}

AnimalLocatorMock.apxc

@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('Charles H Bones Esquire');
        response.setStatusCode(200);
        return response;
    }
}

My code is saved and closed out of and the challenge still fails. Any suggestions would be greatly appreciated. Thanks!
Best Answer chosen by Eric Anderson 54
Alap MistryAlap Mistry
Hi Eric Anderson 54,
Try this code.
AnimalLocator.apxc (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);
        String animals = '';
        
        if(response.getStatusCode() == 200) {
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
            Map<String, Object> animal = (Map<String, Object>)result.get('animal');
            animals = string.valueOf(animal.get('name'));
        }
        return animals;
    }
}
AnimalLocatorTest.apxc
@isTest
private class AnimalLocatorTest {
    @isTest static void AnimalLocatorMock() {
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
        String actual = AnimalLocator.getAnimalNameById(1);
        String expected = 'chicken';
        System.assertEquals(actual, expected);
    }
}
AnimalLocatorMock.apxc
@isTest
global class AnimalLocatorMock implements HttpCalloutMock {
    global HttpResponse respond(HttpRequest request) {
        HttpResponse response = new HttpResponse();
        response.setHeader('contentType', 'application/json');
        response.setBody('{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}');
        response.setStatusCode(200);
        return response;
    }
}
Regards,
Alap Mistry

All Answers

Alap MistryAlap Mistry
Hi Eric Anderson,
Add this site 'https://th-apex-http-callout.herokuapp.com/animals/' in remote site settings.
Regards,
Alap Mistry
Eric Anderson 54Eric Anderson 54
Hi there Alap,

Ya, unfortunately, I added that remote site setting back when I first started struggling with this exercise. Check out the screen shot that I have attached.

I welcome any other suggestions that might be out there!

Thank you!

Eric AndersonUser-added image
Alap MistryAlap Mistry
Hi Eric Anderson 54,
Try this code.
AnimalLocator.apxc (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);
        String animals = '';
        
        if(response.getStatusCode() == 200) {
            Map<String, Object> result = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
            Map<String, Object> animal = (Map<String, Object>)result.get('animal');
            animals = string.valueOf(animal.get('name'));
        }
        return animals;
    }
}
AnimalLocatorTest.apxc
@isTest
private class AnimalLocatorTest {
    @isTest static void AnimalLocatorMock() {
        Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
        String actual = AnimalLocator.getAnimalNameById(1);
        String expected = 'chicken';
        System.assertEquals(actual, expected);
    }
}
AnimalLocatorMock.apxc
@isTest
global class AnimalLocatorMock implements HttpCalloutMock {
    global HttpResponse respond(HttpRequest request) {
        HttpResponse response = new HttpResponse();
        response.setHeader('contentType', 'application/json');
        response.setBody('{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}');
        response.setStatusCode(200);
        return response;
    }
}
Regards,
Alap Mistry
This was selected as the best answer
Eric Anderson 54Eric Anderson 54
Thank you for the help Alap,

As you identified, I missed the fact that I needed to use the 'Map' functions in order to parse the response. Additionally, I needed to provide all of the various attributes for the response, not just the Name.

Thank you again!

- Eric -  
Earl Newcomer 10Earl Newcomer 10
Much appreciated Alap.  I worked for quite a while trying to get over 43% test coverage and your post helped get the rest of the way.
Raghwendra Ji ChaubeyRaghwendra Ji Chaubey
Before run your code, do the following
SETUP =>Remote Site Settings => New Remote Site => https://th-apex-http-callout.herokuapp.com
Berta RogersBerta Rogers
Thank you. This is what I was looking for