+ Start a Discussion
CloudGeekCloudGeek 

Apex REST Test Class Issue (When run in Anonymous window results look good)

Hi,

I have the below test class for my REST Class:
When I run this test class always the returned list is empty though actually I am able to see data on page.
And when I run this test class code from anynymous window - I get to see results are fine with no of rows as expected.

Can anyone help me understand If I am missing something here ?
@isTest
public class OSCTestClass
{

static testMethod void getMeListOfProducts() {
    
    // Set up a test request
    RestRequest request = new RestRequest();

    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'Costco');
    request.params.put('product', 'ALL');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    
    

    
}
}

 
Best Answer chosen by CloudGeek
CloudGeekCloudGeek
Hello Daniel,

The issue is with the Test Data being unavailable.
I did use (SeeAllData = True), it has got good coverage.

Can you help me optimize the below test class , (final one after updated) ? (It is lenghty as I had to write to cover different URL-Parameter combinations)
@isTest(SeeAllData=true)
public class OSCTestClass
{

static testMethod void getMeListOfProducts() {
    
    ApexPages.StandardController ctrl;
    OnlineSalesCatalogController osc = new OnlineSalesCatalogController(ctrl);
    
    // Set up a test request
    RestRequest request = new RestRequest();
   
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'Costco');
    request.params.put('product', 'ALL');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    
    string pwd = OnlineSalesCatalogController.getTempPassword('8');
    System.debug('pwd = '+pwd);

    }
    static testMethod void getMethodTest2()
    {
        // Set up a test request
    RestRequest request = new RestRequest();
    
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'ALL');
    request.params.put('product', 'ALL');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    }
    static testMethod void getMethodTest3()
    {
        // Set up a test request
    RestRequest request = new RestRequest();
    
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'ANY');
    request.params.put('product', 'Plus');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    }
    static testMethod void getMethodTest4()
    {
        // Set up a test request
    RestRequest request = new RestRequest();
    
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'ALL');
    request.params.put('product', 'Plus');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    }
}



 

All Answers

Mahesh DMahesh D
Hi,

You have to write the Mock class to test REST API calls.

Testing HTTP Callouts by Implementing the HttpCalloutMock Interface
Provide an implementation for the HttpCalloutMock interface to specify the response sent in the respond method, which the Apex runtime calls to send a response for a callout.


If this is your Class:
 
public class CalloutClass {
    public static HttpResponse getInfoFromExternalService() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://api.salesforce.com/foo/bar');
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        return res;
    }
}
Mock Class:
@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        // Optionally, only send a mock response for a specific endpoint
        // and method.
        System.assertEquals('http://api.salesforce.com/foo/bar', req.getEndpoint());
        System.assertEquals('GET', req.getMethod());
        
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody('{"foo":"bar"}');
        res.setStatusCode(200);
        return res;
    }
}

Test Class:
@isTest
private class CalloutClassTest {
     @isTest static void testCallout() {
        // Set mock callout class 
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        
        // Call method to test.
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        HttpResponse res = CalloutClass.getInfoFromExternalService();
        
        // Verify response received contains fake values
        String contentType = res.getHeader('Content-Type');
        System.assert(contentType == 'application/json');
        String actualValue = res.getBody();
        String expectedValue = '{"foo":"bar"}';
        System.assertEquals(actualValue, expectedValue);
        System.assertEquals(200, res.getStatusCode());
    }
}

Also go through the below links:

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_http_testing_httpcalloutmock.htm

https://developer.salesforce.com/blogs/developer-relations/2013/03/testing-apex-callouts-using-httpcalloutmock.html

https://developer.salesforce.com/forums/?id=906F0000000BNqcIAG


Please do let me know if it helps you.

Regards,
Mahesh
Daniel BallingerDaniel Ballinger

I suspect you will also need to set the RestContext.response to an instance of System.RestResponse. Then check that for the response.

From Apex REST Methods (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest_methods.htm):

If the Apex method has a non-void return type, the resource representation is serialized into the response body.

Also, have you created the testing data that the getOfferedProductsList() method will access. I assume it is doing some type of SOQL query internally.

CloudGeekCloudGeek
Hi Folks,

Thanks for quick response!

Here is my original class:
 
@RestResource(urlMapping='/OSCList/*')

global with sharing class OnlineSalesCatalogController {
    
   
    public OnlineSalesCatalogController( ApexPages.StandardController ctrl ) { }
 
    
    @HttpGet
    global static List<OnlineSalesCatalogWrapper> getOfferedProductsList() 
    {
        RestRequest req = RestContext.request;
        
        String region = req.params.get('region');
        String segment= req.params.get('segment');
        String product = req.params.get('product');
        
        /*
        region = (!String.isBlank(region))? region : 'USA';
        segment = (!String.isBlank(segment))? segment : 'ALL'; 
        product = (!String.isBlank(product))? product : 'ALL';  */
        
        
        System.debug('@@@ params region= '+region+' segment='+segment+' product='+product);
        
        List<OnlineSalesCatalogWrapper> wrappers = new List<OnlineSalesCatalogWrapper>();
        wrappers = OnlineSalesCatalogHelper.getOnlineSalesCatalogWrapperForRegion( region );
        
        System.debug('@@@ wrappers from OnlineSalesCatalogHelper.getOnlineSalesCatalogWrapperForRegion( region ) METHOD ===='+wrappers);
        
        List<OnlineSalesCatalogWrapper> wrappersWithFilters = new List<OnlineSalesCatalogWrapper>();
        List<OnlineSalesCatalogWrapper> finalWrappers = new List<OnlineSalesCatalogWrapper>();
        
        if(!segment.equalsIgnoreCase('ALL') && !product.equalsIgnoreCase('ALL') && !(wrappers.isEmpty()))
        {
            
            for(OnlineSalesCatalogWrapper w : wrappers)
                {
                     if(w.segment.equalsIgnoreCase(segment) && w.displayProductName.containsIgnoreCase(product))
                     {
                         wrappersWithFilters.add(w);
                     }   
                }
             finalWrappers =  wrappersWithFilters.clone();               
        }
else if(segment.equalsIgnoreCase('ALL') && !product.equalsIgnoreCase('ALL') && !(wrappers.isEmpty()))
{
    for(OnlineSalesCatalogWrapper w : wrappers)
                {
                     if(w.displayProductName.containsIgnoreCase(product))
                     {
                         wrappersWithFilters.add(w);
                     }   
                }
             finalWrappers =  wrappersWithFilters.clone(); 
} 

else if(!segment.equalsIgnoreCase('ALL') && product.equalsIgnoreCase('ALL') && !(wrappers.isEmpty()))
{
    for(OnlineSalesCatalogWrapper w : wrappers)
                {
                     if(w.segment.equalsIgnoreCase(segment))
                     {
                         wrappersWithFilters.add(w);
                     }   
                }
             finalWrappers =  wrappersWithFilters.clone(); 
}         
        
else { finalWrappers = wrappers.clone(); }         
     
        
        return finalWrappers;
    
    }

Always, the wrappers list is empty() from Test Class. But on Page data is fine.
Daniel BallingerDaniel Ballinger
What do your debug statements in getOfferedProductsList() show when the test is run?
CloudGeekCloudGeek
Hello Daniel,

The issue is with the Test Data being unavailable.
I did use (SeeAllData = True), it has got good coverage.

Can you help me optimize the below test class , (final one after updated) ? (It is lenghty as I had to write to cover different URL-Parameter combinations)
@isTest(SeeAllData=true)
public class OSCTestClass
{

static testMethod void getMeListOfProducts() {
    
    ApexPages.StandardController ctrl;
    OnlineSalesCatalogController osc = new OnlineSalesCatalogController(ctrl);
    
    // Set up a test request
    RestRequest request = new RestRequest();
   
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'Costco');
    request.params.put('product', 'ALL');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    
    string pwd = OnlineSalesCatalogController.getTempPassword('8');
    System.debug('pwd = '+pwd);

    }
    static testMethod void getMethodTest2()
    {
        // Set up a test request
    RestRequest request = new RestRequest();
    
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'ALL');
    request.params.put('product', 'ALL');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    }
    static testMethod void getMethodTest3()
    {
        // Set up a test request
    RestRequest request = new RestRequest();
    
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'ANY');
    request.params.put('product', 'Plus');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    }
    static testMethod void getMethodTest4()
    {
        // Set up a test request
    RestRequest request = new RestRequest();
    
    // Set request properties
    String sfdcBaseURL = URL.getSalesforceBaseUrl().toExternalForm();
    System.debug('sfdcBaseURL = '+sfdcBaseURL);
    
    request.requestUri = sfdcBaseURL+'/services/apexrest/onlinesalesUIcatalogueNew/';
    request.httpMethod = 'GET';
     
    request.params.put('region', 'USA');
    request.params.put('segment', 'ALL');
    request.params.put('product', 'Plus');
    
    RestContext.request = request;
    
    List<OnlineSalesCatalogWrapper> results = new List<OnlineSalesCatalogWrapper>();
    
    results = OnlineSalesCatalogController.getOfferedProductsList();
    System.debug('size of results = '+results.size());
    }
}



 
This was selected as the best answer