+ Start a Discussion

Unit Test, Callout No Response with Static Resource

Bit stuck on another one i'm afraid, i am trying to write a unit test for a bulk APEX class.


The class has a calllout to the google api, so i have created a static resource which i am feeding in via a mock, so i can complete testing of processing the JSON that is returned. However for some reason the response is always empty.


Now the very odd thing is that if i use exactly the same callout/JSON code, and the same mock code on a previous @future call, then it does return fine.


Here is the class:


global class mileage_bulk implements Database.Batchable<sObject>,



global Database.QueryLocator start(Database.BatchableContext BC)


String query = 'SELECT Id,Name,Amount,R2_Job_Ref__c,R2_Shipping_Post_Code__c,Shipping_Postcode_2__c FROM Opportunity WHERE R2_Shipping_Post_Code__c != null';

return Database.getQueryLocator(query);




global void execute(Database.BatchableContext BC, List<Opportunity> scope)



for(Opportunity a : scope)



        String startPostcode = null;

        startPostcode = EncodingUtil.urlEncode('HP27DU', 'UTF-8');

        String endPostcode = null;

        String endPostcodeEncoded = null;

        if (a.R2_Shipping_Post_Code__c != null){

        endPostcode =   a.R2_Shipping_Post_Code__c;

        Pattern nonWordChar = Pattern.compile('[^\\w]');

endPostcode = nonWordChar.matcher(endPostcode).replaceAll('');

        endPostcodeEncoded =   EncodingUtil.urlEncode(endPostcode, 'UTF-8');


        Double totalDistanceMeter = null;

        Integer totalDistanceMile = null;

       String responseBody = null;

       Boolean firstRecord = false;


        String ukPrefix = 'UKH';

        if (a.R2_Job_Ref__c != null){    

        if ((a.R2_Job_Ref__c).toLowerCase().contains(ukPrefix.toLowerCase())){

        system.debug('Is Hemel Job');

        startPostcode = EncodingUtil.urlEncode('HP27DU', 'UTF-8');

        } else {

        system.debug('Is Bromsgrove Job');

        startPostcode = EncodingUtil.urlEncode('B604AD', 'UTF-8');




        // build callout

        Http h = new Http();

        HttpRequest req = new HttpRequest();




        system.debug('request follows');




            // callout

            HttpResponse res = h.send(req);


            // parse coordinates from response


            JSONParser parser = JSON.createParser(res.getBody());


            responseBody = res.getBody();



            while (parser.nextToken() != null) {

                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && 

                    (parser.getText() == 'distance')){

                       parser.nextToken(); // object start

                       while (parser.nextToken() != JSONToken.END_OBJECT){

                           String txt = parser.getText();




                           if (firstRecord == false){

                           //if (txt == 'text'){

                               //totalDistanceMile = parser.getText();



                           if (txt == 'value'){

                               totalDistanceMeter = parser.getDoubleValue();

                               double inches = totalDistanceMeter*39.3701;

                               totalDistanceMile = (integer)inches/63360;


                               firstRecord = true;









        } catch (Exception e) {









            // update coordinates if we get back 

            if (totalDistanceMile != null){

            system.debug('Entering Function to Update Object');

                a.DistanceM__c = totalDistanceMile;

                a.Shipping_Postcode_2__c = a.R2_Shipping_Post_Code__c;

                //update a;        



update scope;




global void finish(Database.BatchableContext BC)





and here is the test class;



 * This class contains unit tests for validating the behavior of Apex classes

 * and triggers.


 * Unit tests are class methods that verify whether a particular piece

 * of code is working properly. Unit test methods take no arguments,

 * commit no data to the database, and are flagged with the testMethod

 * keyword in the method definition.


 * All test methods in an organization are executed whenever Apex code is deployed

 * to a production organization to confirm correctness, ensure code

 * coverage, and prevent regressions. All Apex classes are

 * required to have at least 75% code coverage in order to be deployed

 * to a production organization. In addition, all triggers must have some code coverage.


 * The @isTest class annotation indicates this class only contains test

 * methods. Classes defined with the @isTest annotation do not count against

 * the organization size limit for all Apex scripts.


 * See the Apex Language Reference for more information about Testing and Code Coverage.



private class mileage_bulk_tests{


    static testMethod void myUnitTest() {

         Opportunity opp1 = new Opportunity(name = 'Google Test Opportunity',R2_Job_Ref__c = 'UKH12345',R2_Shipping_Post_Code__c = 'AL35QW',StageName = 'qualified',CloseDate = Date.today());

 insert opp1;

 Opportunity opp2 = new Opportunity(name = 'Google Test Opportunity 2',StageName = 'qualified',CloseDate = Date.today());

 insert opp2;

 Opportunity opp3 = new Opportunity(name = 'Google Test Opportunity 3',R2_Job_Ref__c = 'UKB56789',R2_Shipping_Post_Code__c = 'AL35QW',StageName = 'qualified',CloseDate = Date.today());

insert opp3;



StaticResourceCalloutMock mock = new StaticResourceCalloutMock();


mock.setStatusCode(200); // Or other appropriate HTTP status code

mock.setHeader('Content-Type', 'application/json'); // Or other appropriate MIME type like application/xml


//Set the mock callout mode

Test.setMock(HttpCalloutMock.class, mock);





//Call the method that performs the callout


mileage_bulk b = new mileage_bulk();

database.executeBatch((b), 10);





Help greatly appreciated!







Also, if i run this class manually by triggering it from force IDE it runs as expected.