1

I have a utility class where we use to call when making request. This request can be with different classes that uses the this utility class.

Here is the sample:

public with sharing class SampleAPIUtility 
{    
   public static String ConnectToSampleAPI(String jsonRequest)
   {

       HttpRequest req = new HttpRequest();
       req.setEndpoint('https://test.com/Api/Test/');
       req.setMethod('POST');

       req.SetBody(jsonRequest);
       req.setHeader('Content-Type', 'application/json');
       req.setTimeout(120000);
       req.setHeader('Content-Length', '300000'); 

       Http http = new Http(); 
       HTTPResponse res = http.send(req);

       return res.getBody();
   }
}

Here is the sample class with method that uses the utility class above:

global with sharing class ImportRecord implements Schedulable
{
   //Omitted some codes
   @future (callout=true)
   public static void SampleImportRecord()
   {
       //omitted some codes

       jsonQuery = SampleAPIUtility.GetObjectJSONString(id);
       jsonOutput = '';
       if(!Test.isRunningTest())
           jsonOutput = SampleAPIUtility.ConnectToSampleAPI(jsonQuery);

       //ommitted some codes

   }

   //omitted some codes
}

Here is the class for mock callout:

@isTest
public class TestHttpResponseGenerator implements HttpCalloutMock 
{
   // Implement this interface method
   public HTTPResponse respond(HTTPRequest req) 
   {
       HttpResponse res = new HttpResponse();
       res.setHeader('Content-Type', 'application/json');
       res.setBody(TestHttpResponseResult.GetObjectJSONResult());
       res.setStatusCode(200);
       return res;
    }
}

Test Method:

@isTest
private class ImportRecordTest {

    static testMethod void testImportRecord() {

        //omitted codes

        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new TestHttpResponseGenerator());
        String schedule = '0 0 0 * * ?';        
        system.schedule('Testing ImportRecordClass', schedule, new ImportRecord()); 
        Test.stopTest();
   }
}

First, the TestHttpResponseResult.GetObjectJSONResult() is just a class with a method that return string in a json format. How can I use the mockhttpcallout in Utility class that is being use in different class with different set of json string. I want this SampleAPIUtility.ConnectToSampleAPI(jsonQuery); to access the response of the mockcallout instead of the response from the external server. Would there be a way to do that?

4
  • Does your test method make use of the Test.setMock() method? – martin Jun 29 '15 at 5:26
  • yes. Oh! I forgot to include the test method. – rpm07 Jun 29 '15 at 5:27
  • Is it working? From what I see here, if you get rid of the: if(!Test.isRunningTest()) you should be fine. – martin Jun 29 '15 at 6:00
  • @martin, no it's not. the external callout is used with different request. how am I able to know which test request I'm getting? – rpm07 Jun 29 '15 at 7:23
1

So, sometime before you make the external callout, you are going to want to create an instance of your mock responder:

TestHttpResponseGenerator thrg = new TestHttpResponseGenerator();

And then set the mock for the test:

Test.setMock(HttpCalloutMock.class, thrg);

Also, at some point you will have to get rid of this line:

if(!Test.isRunningTest())

You should also surround your callout in the test method with:

Test.startTest();
//callout
Test.stopTest();

stopTest() will get all of the pending async processes to be run synchronously.

Update: If you want your httpresponder mock test class to be able to provide different responses, you could do something like this:

@isTest
public class TestHttpResponseGenerator implements HttpCalloutMock 
{
   String theJSONResponse;

   public TestHttpResponseGenerator(/* some parameter to indicate which response you want */){
       this.theJSONResponse =  TestHttpResponseResult.GetObjectJSONResult(/* that parameter */);
   }
   // Implement this interface method
   public HTTPResponse respond(HTTPRequest req) 
   {
       HttpResponse res = new HttpResponse();
       res.setHeader('Content-Type', 'application/json');
       res.setBody(theJSONResponse);
       res.setStatusCode(200);
       return res;
    }
}

Then you can create test methods for each of the possible return values of the service you are working with by setting that value in the constructor of the mock. By the way, you should probably also make the status code settable in a similar way since you aren't always going to be guaranteed to get a 200 response.

10
  • Oh! I never thought of using the constructor to pass the type of response. – rpm07 Jun 29 '15 at 7:59
  • for some reason it's not getting the response from the mockcallout. mockcallout work whenever there is a callout right? – rpm07 Jun 29 '15 at 8:53
  • @robertpeter07 Yes, it should always provide the response that you return in the respond method. I don't know if you've changed your code since the last edit on this site, but one issue could be this line: if(!Test.isRunningTest()) is preventing the callout from happening during the test. – martin Jun 29 '15 at 8:57
  • i have removed that. does the schedule matter? – rpm07 Jun 29 '15 at 9:04
  • @robertpeter07 It should be happening when you call Test.stopTest(). – martin Jun 29 '15 at 9:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.