1

I am writing test classes for apex classes code coverage. In one apex class, I am sending request to a website and getting response in json format. Then I am deserializing the response string into inner-class objects. That portion is not being covered by me.

My Apex class code is:

public class SearchCompanyApex {
    public SearchResultJSON sJsonR{get;set;}
    public string myAPIKey {get; set;}
    public List<IncomeStatement> listIncomeStateValues{get;set;}

    public string result_of_httpReq {get; set;}


    public void loadPage(){
        string symbol = queryString('c');

        if(symbol !=null || symbol !='' ){                                                     
            generalInfo(symbol);    
        }
    }

    // Method that is requesting the data from website and assigning the data to variables of this class..
    private void generalInfo(string symbol){

        result_of_httpReq =  httpReq(symbol);
        sJsonR = (SearchResultJSON)JSON.deserialize(result_of_httpReq, SearchResultJSON.class);

    //=================== Not Covered code Start ================== Main is sJsonR.items[0].attributes not covered...  

        // Adding values in list to use it to save data in salesforce..  
        listIncomeStateValues = new List<IncomeStatement>{
            new IncomeStatement('Description', sJsonR.items[0].description,'Description__c'),
            new IncomeStatement('Company Title', sJsonR.items[0].title,'Name')
        };

    //=================== Not Covered code End  ===================

    }


    // Class to make a json obect containing the inoformation of all the fields of this class..
    public Class SearchResultJSON{
        public List<SearchedDocs> items;
    }

    public Class SearchedDocs{
        public string description{get;set;}
        public string title {get;set;}
        public list<list<string>> data{get;set;}
    }


    // Wrapper Class for CompaniesHouse Data 
    Public Class IncomeStatement{
        Public String Field{get;set;}
        Public String Value{get;set;}
        Public String SFField{get;set;}
        Public String SFValue{get;set;}


       // Constructor. Initializing values...
        public IncomeStatement(string Field, string Value,string SFField){
            this.Field = Field;
            this.Value = Value;
            this.SFValue = Value;
            this.SFField = SFField;
        }
    }
}

And Test Class code is:

@isTest
public with sharing class SearchCompanyApex_TestClass {

     static testMethod void myTest() {

        // Making object of class to be covered...
        SearchCompanyApex class_test = new SearchCompanyApex();

        // Making object of inner class of target class to be covered...
        SearchCompanyApex.SearchedDocs jsonobject_test = new SearchCompanyApex.SearchedDocs();
        jsonobject_test.description = 'Company description';
        jsonobject_test.title = 'Company Name';

        // Making list for different objects to map into fields...
        List<SearchCompanyApex.IncomeStatement> listJSONDocs = new List<SearchCompanyApex.IncomeStatement>();

        SearchCompanyApex.IncomeStatement list_description = new SearchCompanyApex.IncomeStatement('Description', jsonobject_test.description, 'Description__c');
        SearchCompanyApex.IncomeStatement list_company_title = new SearchCompanyApex.IncomeStatement('Company Title', jsonobject_test.title, 'Name');

        listJSONDocs.add(list_description);
        listJSONDocs.add(list_company_title);

        class_test.listIncomeStateValues = listJSONDocs;
        // Checking whether Website API key is equal to the saved key...    
        System.assertEquals(class_test.listIncomeStateValues, listJSONDocs);


        // It is the main part of this test class. It is call to "getAPIKeyMock" to avoid error : "Methods defined as TestMethod do not support Web service callouts." 
        Test.setMock(HttpCalloutMock.class, new GetAPIKeyMock(class_test.result_of_httpReq));

        // Calling the method "loadPage()" ...
        class_test.loadPage(); 


        SearchCompanyApex.SearchResultJSON jsonList_test = new SearchCompanyApex.SearchResultJSON();
        jsonList_test.items.add(jsonobject_test);

        class_test.sJsonR.items[0].title = jsonList_test.items[0].title;
        class_test.sJsonR.items[0].description = jsonList_test.items[0].description;


        // Checking whether Website API key is equal to the saved key...    
        System.assertEquals(class_test.sJsonR.items[0].title, 'Company Name');

        // Checking whether Website API key is equal to the saved key...    
        System.assertEquals(class_test.sJsonR.items[0].description, 'Company description');

    }


    // This is an inner class to handle WebService callout problems.
    private class GetAPIKeyMock implements HttpCalloutMock {
        private string returned_SJSONResult;

        public GetAPIKeyMock(string returned_SJSONResult) {
            this.returned_SJSONResult = returned_SJSONResult;
        }

        public HTTPResponse respond(HTTPRequest req) {
            // you can use System.assert here and "if" calls to check the request and affect your return if you wish

            HttpResponse res = new HttpResponse();
            res.setBody(returned_SJSONResult);
            return res;
        }
    }
}

Note: The uncovered code in shown in comments... How can we cover this code? Please tell me. Any help will be appreciated.

6
  • Can you please take some time and remove irrelevant code from your question so it is easier to read?
    – Adrian Larson
    Commented Jan 6, 2016 at 7:33
  • I have done it. Commented Jan 6, 2016 at 7:50
  • can you confirm thats there only 4 lines are not covered? cause as soon as you call loadPage method and symbol is not empty -- those lines should be covered
    – kurunve
    Commented Jan 6, 2016 at 9:10
  • Yes, only these four lines are not covered. And The inner class just below the uncovered lines is neither showing as covered nor as uncovered. It shows no effect. Is this a problem? Commented Jan 6, 2016 at 9:37
  • @KhawajaM.Awais I would suggest you to clear code coverage and rerun tests, because sometimes code coverage is showing weird, especially when you run tests from Developers Console
    – kurunve
    Commented Jan 6, 2016 at 9:43

3 Answers 3

1

Im on mobile so apologies for brevity, but you can consider a few approaches. Either write a mock webservice (https://developer.salesforce.com/blogs/developer-relations/2013/03/testing-apex-callouts-using-httpcalloutmock.html)

or

take this (http://blog.wdcigroup.net/2012/08/salesforce-web-service-callout-test-class/) approach, which is to return a hardcoded result to simulate the webservice callout. Hope this points you to what you need.

1

It looks to me that your HttpMock returns null

Test.setMock(HttpCalloutMock.class, new GetAPIKeyMock(class_test.result_of_httpReq));

The value of class_test.result_of_httpReq is null when the mock class's constructor is called.

Instead, you should do something like this

Test.setMock(HttpCalloutMock.class, new GetAPIKeyMock(someJsonString));

then, when the testmethod does:

class_test.loadPage();

which in turn makes an HTTP request, SFDC will invoke the mock class's respond() method that in turn returns the value of someJsonString to your PROD code.

You can build up a library of differentsomeJsonString in static resources if they are complex and cycle through in different testmethods

1
  • Yes, I have got the answer. You are same to my answer. Commented Jan 7, 2016 at 6:14
0

I have got answer for the question and is working for me. Here we have to make some minor changes in code, where we are creating GetAPIKeyMock object and calling its constructor, here we have to pass the string containing response result of httpRequest in json format. We can get the response result from our org. by using System.debug logs, then store it in string variable and then pass that variable in GetAPIKeyMoc, Then it will cover the uncovered lines of code. In simple words, It will cover json.deserialized object as required.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .