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
Suresh(Suri)Suresh(Suri) 

Need help on code coverage for json parser

Need help for Code coverage to json parser in locationcallouts apex class
Hi,

Need to help for code coverage i got 66% but json part not coveing in my controller please look into my code
================Apex Class====================
public class LocationCallouts {

     @future (callout=true)  // future method needed to run callouts from Triggers
      static public void getLocation(id accountId){
        // gather account info
        Account a = [SELECT BillingCity,BillingCountry,BillingPostalCode,BillingState,BillingStreet FROM Account WHERE id =: accountId];
 
        // create an address string
        String address = '';
        if (a.BillingStreet != null)
            address += a.BillingStreet +', ';
        if (a.BillingCity != null)
            address += a.BillingCity +', ';
        if (a.BillingState != null)
            address += a.BillingState +' ';
        if (a.BillingPostalCode != null)
            address += a.BillingPostalCode +', ';
        if (a.BillingCountry != null)
            address += a.BillingCountry;
 
        address = EncodingUtil.urlEncode(address, 'UTF-8');
        
        General_Settings__c ge= General_Settings__c.getValues('API Key');
        General_Settings__c eurl= General_Settings__c.getValues('Geocoding URL');        
        System.debug('##########'+eurl);
        System.debug('@@@@@@@@@@'+ge);
        String geocodingKey = ge.Value__c;
        String endpointurl= eurl.Value__c;
 
        // build callout
        Http h = new Http();
        HttpRequest req = new HttpRequest();
      //req.setEndpoint('http://maps.googleapis.com/maps/api/geocode/json?address='+address+'&sensor=false');
        req.setEndpoint(endpointurl+'?address='+ address + '&key=' + geocodingKey + '&sensor=false');
        req.setMethod('GET');
        req.setTimeout(60000);
 
        try{
            // callout
            HttpResponse res = h.send(req);
             System.debug('&&&&&'+res.getBody());
             System.debug('#####');
            // parse coordinates from response
            JSONParser parser = JSON.createParser(res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }
 
                }
            }
 
            // update coordinates if we get back
            if (lat != null){
                a.GeoLocations__Latitude__s = lat;
                a.Location_Latitude__c = lat;
                a.GeoLocations__Longitude__s = lon;
                a.Location_Longitude__c = lon;
                Lat= lat;
                Lon= lon;
                update a;
            }
 
        } catch (Exception e) {
        }
    }
}
===================ApexTest Class===================
@IsTest(SeeAllData=False)
public class Test_LocationCallouts {
    static testMethod void validateLocationCallouts() {
   
    General_Settings__c setting1 = new  General_Settings__c();
    setting1.Name = 'Geocoding URL';
    setting1.Value__c = 'https://maps.googleapis.com/maps/api/geocode/json';
    insert setting1;
    General_Settings__c setting2 = new  General_Settings__c();
    setting2.Name = 'API Key';
    setting2.Value__c = 'AIzaSyBdTDHIFZgg1lG_p9fCg5QYcWWKrWe6K_E';
    insert setting2;
   
    Account a = new Account(Name='Testsup', BillingCountry='USA',BillingState='New Jersey',BillingCity='Cliff Wood',
                            BillingPostalCode='07010',BillingStreet='cliff wood');
    insert a;

        LocationCallouts.getLocation(a.id);
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        Test.stopTest();
        HttpResponse res = CalloutClass.getInfoFromExternalService(); 
    }
}

================Dummy callout class===========
@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
    global HTTPResponse respond(HTTPRequest req) {
        // Create a fake response.
        // Set response values, and
        // return response.
        system.debug('Mock ApiListMtgListMeetingsResult');
       
        //System.assertEquals('http://api.salesforce.com/foo/bar', req.getEndpoint());
        System.assertEquals('GET', req.getMethod());

 
       HttpResponse res = new HttpResponse();
       res.setHeader('Content-Type', 'text/xml;charset=UTF-8');
       //req.setEndpoint('http://maps.googleapis.com/maps/api/geocode/json?address='+address+'&sensor=false');
       res.setBody('{"name":"testrec","billingcountry":"United States","BillingState":"New Jersey","BillingCity":"California","BillingPostalcode":"07010","lat":37.386,"lon":-122.084}');
       res.setStatusCode(200);
       return res; 
       
    }
}
===============Coverage Status===============


Can any one help?
User-added image
Best Answer chosen by Suresh(Suri)
Rohit K SethiRohit K Sethi
hi Suresh(Suri),

you are setting the mock in test class this will sets the fack respose. So in json you must to be define the location as key and any value so that your condtion get satisfy. 
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
example :
res.setBody('{"name":"testrec","billingcountry":"United States","BillingState":"New Jersey","BillingCity":"California","BillingPostalcode":"07010","lat":37.386,"lon":-122.084,"location":Ajmer}');

And one more thing before calling getLocation method you need to be set the mock in test class so use as follow:
example :
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        LocationCallouts.getLocation(a.id);
        Test.stopTest();

Thanks.

All Answers

Rohit K SethiRohit K Sethi
hi Suresh(Suri),

you are setting the mock in test class this will sets the fack respose. So in json you must to be define the location as key and any value so that your condtion get satisfy. 
if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
example :
res.setBody('{"name":"testrec","billingcountry":"United States","BillingState":"New Jersey","BillingCity":"California","BillingPostalcode":"07010","lat":37.386,"lon":-122.084,"location":Ajmer}');

And one more thing before calling getLocation method you need to be set the mock in test class so use as follow:
example :
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        LocationCallouts.getLocation(a.id);
        Test.stopTest();

Thanks.
This was selected as the best answer
Suresh(Suri)Suresh(Suri)
Hi Rohit,

Thanks for your quick reply. I have modified my code as you mectioned but still same coverage not covered that lines.
please look my new code below.
===============Mock test class=============
@isTest
global class mockHttpResponseGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        System.assertEquals('GET', req.getMethod());
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        //res.setBody('{"query":"Select Id from Account","columns":[ {"ascendingLabel" : "Z-A","label" : "Account Name","fieldNameOrPath" : "Account Name","hidden":false}]}');
        res.setBody('{"name":"testrec","billingcountry":"United States","BillingState":"New Jersey","BillingCity":"California","BillingPostalcode":"07010","lat":37.386,"lon":-122.084,"location":Ajmer}');
        res.setStatusCode(200);
        return res;
    }
}
=======================Test Class===============
@isTest
public class Test_LocationCallouts {
    static testMethod void validateLocationCallouts() {
    General_Settings__c setting1 = new  General_Settings__c();
    setting1.Name = 'Geocoding URL';
    setting1.Value__c = 'https://maps.googleapis.com/maps/api/geocode/json';
    insert setting1;
    General_Settings__c setting2 = new  General_Settings__c();
    setting2.Name = 'API Key';
    setting2.Value__c = 'AIzaSyBdTDHIFZgg1lG_p9fCg5QYcWWKrWe6K_E';
    insert setting2;
    Account acc=new Account();
            acc.Name = 'Test Account';
            acc.BillingCountry='USA';
            acc.BillingState='New Jersey';
            acc.BillingCity='Cliff Wood';
            acc.BillingPostalCode='07010';
            acc.BillingStreet='cliff wood';
            //acc.location='Ajmer';
        insert acc;
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        LocationCallouts.getLocation(acc.id);
        Test.stopTest();
        HttpResponse res = CalloutClass.getInfoFromExternalService();
    }
}

Can you help on this?
Suresh(Suri)Suresh(Suri)
Hi Rohit,
Its working fine but i modified my code little bit change.
updated code
  res.setBody('{"name":"testrec","billingcountry":"United States","BillingState":"New Jersey","BillingCity":"California","BillingPostalcode":"07010","location":{'+'"lat" : 37.79410130,'+'"lon":-122.39510960'+'}}');

I added lat and lang values inside location after that my code executed 100%.

Thanks Rohit for you kind information.