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
AaranAaran 

Writing a test class for callout

Can somebody help me to write a test class for this batch class pls?

 

global class LeadCallOutBatchable implements Database.Batchable<sObject>, Database.AllowsCallouts{

global final String Query;

   global final String Entity;

 

   global LeadCallOutBatchable() {

      Query='SELECT Id, FirstName, LastName, UserName__c, Email, Title, fs_skills__c, fs_overview__c, fs_facebook__c, fs_twitter__c, fs_linkedin__c ' +

              'FROM Lead WHERE UserName__c != null';  

        Entity= 'Lead';

   }

 

   global Database.QueryLocator start(Database.BatchableContext BC) {

      return Database.getQueryLocator(query);

   }

    

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

        

        List<Lead> leadsToUpdate = new List<Lead>();

        String PersonURL ;

        Integer count = 0;

        System.debug('scope: ' + scope);

        

        for(Lead leadRec : scope ) {   

            String jResponse = '';

            JPersonList deserialPersonList = new JPersonList();

            count++;

            System.debug('Count: ' + count);           

            PersonURL =  URL

            

            try {

                HttpRequest req = new HttpRequest();

                req.setMethod('GET');

                String username = JUSERNAME;

                String password = JPW;

                Blob headerValue = Blob.valueOf(JUSERNAME + ':' + JPW);

                String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);

                req.setHeader('Authorization', authorizationHeader);

                req.setHeader('Accept', 'application/json');

                req.setEndPoint(PersonURL);

                

                Http http = new Http();

                system.debug('req: ' + req);

                HTTPResponse res = http.send(req);

         

               jResponse = res.getBody();

                

 

                jResponse = jResponse.Replace('throw \'allowIllegalResourceCall is false.\';', '');    

                //System.debug('Request Body: ' + jResponse);

                

                JSONParser parser = JSON.createParser(jResponse);

 

  // deserialize

                JObject personRecord = (JObject) System.JSON.deserialize(jResponse, JObject.class);

 

              

                /*[

BLOCK OF CODES TO COMPARE             

]*/

                

                       leadsToUpdate.add(leadRec);

                       System.debug('leadsToUpdate: ' + leadsToUpdate);

            }

            }

            catch(Exception ex) {

                System.debug('Exception: ' + ex);   

            }

        }

        System.debug('leadsToUpdate: ' + leadsToUpdate);

        update leadsToUpdate;

    }

        

   global void finish(Database.BatchableContext BC){ 

   }

}

magicforce9magicforce9

Hi,

 

You need to create two test classes MockHTTP class and BatchTest Class, below is the sample for both.

 

MockHTTP Class

@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        res.setBody(getJSONBody());
        res.setStatusCode(200);
        return res;
    }
    global string getJSONBody()
    {
    
    //You need to structure you'r sample JSON reponse into a String. In this reponse you'll need to specify values that you'll be using to do an Assert at the end of TestBatchClass
    String json = '{'+
		'\"kind\": \"someKind\",'+
		'\"etag\": \"\\\"jSwUP5mXUGwzAFbnLazODtWp_hU/xkmGPffByZklbXyXQDh4klvmhzo\\\"\",'+
		'\"pageInfo\": {'+
		'\"totalResults\": 1,'+
		'\"resultsPerPage\": 1'+
		'},'+
		'\"items\": ['+
		'{'+
		'\"kind\": \"someKind\",'+
		'\"etag\": \"\\\"jSwUP5mXUGwzAFbnLazODtWp_hU/YXgdzso7M5zhQmxu42URIvfh6VE\\\"\",'+
		'\"id\": \"someID\",'+
		'\"statistics\": {'+
		'\"viewCount\": \"87896\",'+
		'\"commentCount\": \"8\",'+
		'\"subscriberCount\": \"657\",'+
		'\"hiddenSubscriberCount\": false,'+
		'\"videoCount\": \"93\"'+
		'}'+
		'}'+
		']'+
		'}';
    return json;
    }
}

 

TestBatchClass

@isTest
private class TestBatchClass {

    static testMethod void executeBatchJob() {
        
    	/* Populate the date for your lead object and make sure you populate all the field so that this record gets queried in your Start() method */
    	Lead lead = new Lead(Firstname = 'some name', LastName = 'some name', Company = 'some company', UserName__c = 'some username');
        insert lead;
        
        Test.setMock(HttpCalloutMock.class, new MockBatchHttpResponseGenerator());
        Test.startTest();
        Database.executeBatch(new LeadCallOutBatchable(), 10);
        Test.stopTest();
        
        List<Lead> updatedLeads = [Select Updated_Fields__c from Lead where id = :lead.id];
        system.assertEquals(updatedLeads[0].Updated__field , 'has the values from JSON reponse in mock batch class'); 
    }
}

 

 

AaranAaran

Thanks for your help Mohammed.  I am getting following message when I run my code. 

 

"09:59:06:505 USER_DEBUG [75]|DEBUG|Exception: System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out"

 

and it's started to fail after HTTP callout and fails at this line:  

 jResponse = res.getBody();

jResponse = jResponse.Replace('throw \'allowIllegalResourceCall is false.\';', ''); 

 

Please help me!

 

Thank you

magicforce9magicforce9

Hi,

 

There is grave restriction from salesforce that you can't make callout after insert. You can try two variants.

 

Try inserting the lead  after Test.StartTest() method.

        
        Test.setMock(HttpCalloutMock.class, new MockBatchHttpResponseGenerator());
        Test.startTest();
Insert lead;
Database.executeBatch(.......

 

or 

 

Make a callout after Test.StopTest.

Test.StartTest();
insert lead;
Test.StopTest();
Datebase.executeBatch(....

 

Hope this fixes it.

AaranAaran

Thanks for your quick response Mohammed.

 

I'm getting following msg:  "DEBUG|Exception: System.TypeException: Methods defined as TestMethod do not support Web service callouts, test skipped"  for the following variant

 

Test.startTest();
Insert testLead;
Database.executeBatch(....);
Test.stopTest();
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());