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
Sanchivan SivadasanSanchivan Sivadasan 

JSON.Deserialize does not create test coverage for the Class?

Hi there,

I have a JSON that is being returned from an HTTP Callout and for which I am using an Apex Class to deserialize. Everything is working as expected when I test it through the developer console. But when I write test coverage, the class for which I am deserializing to is showing up as not covered by the test class.

Does the JSON.deserialize cover the class that it's deserializing to or does it not? Thanks.

Sanch.
 
{!pramod_nishane}{!pramod_nishane}
Hi Sanchivan Sivadasan,

You have to create fake response to cover JSON.deserialize.
you can write mock response class and test the same.

here is simple example for your reference:-


public class AnimalLocator {
    
    public class AnimalInstanceClass {
        public Integer id;    
        public String name;    
        public String eats;    
        public String says;    
    } 
    
    public class JSONResponseClass{
        public AnimalInstanceClass animal;
    }
    
    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);
        system.debug('response: ' + response.getBody());
        JSONResponseClass results = (JSONResponseClass) JSON.deserialize(response.getBody(), JSONResponseClass.class);
        system.debug('results= ' + results.animal.name);
        return(results.animal.name);
    }

}

Test Class:-

@IsTest
global 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);
    }

}

Mock Class:- 

@IsTest
global class AnimalLocatorMock implements HttpCalloutMock {
    
    global HTTPresponse respond(HTTPrequest request) {
        Httpresponse response = new Httpresponse();
        response.setStatusCode(200);
        response.setBody('{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}');
        return response;
    }

}


Let me know in case of any concerns.

Please mark this answer as the solution/ best answer if it solves your purpose so that it can help other community members.

Thanks,
Pramod Nishane
Salesforce Consultant
Varasi LLC
www.varasi.com
Sanchivan SivadasanSanchivan Sivadasan
Hi Pramod,

That's exactly what I did and what I noticed when you do deserialize in your case to JSONResponseClass, it doesn't create code coverage for JSONResponseClass and AnimalInstanceClass. What I had to do is, rather than setting the response as a string, I had to create an object representation of the string using JSONResponseClass and AnimalInstanceClass and then serialize that and set that as the response. Not sure why the deserialize by it self should not cover the class.

Sanchivan S.