3

I have batch class that makes a HTTP callout to a remote web service. To deploy into production, I have created a test class with StaticResourceCalloutMock.

I am executing the test class in a full copy sandbox and it is working fine. But when I deploy, it is failing. Not sure what is going on.

Getting the following error message

System.NullPointerException: Attempt to de-reference a null object Stack Trace: Class.InsideviewPostJob.IVPostRequest: line 26, column 1 Class.AccountAPIToInsideviewRequest.Execute: line 37, column 1

Deployment is failing at the following line in the class - InsideviewPostJob

if (res.getStatus()=='OK' && res.getstatuscode()==200) {

Test Class:

        test.startTest();
         StaticResourceCalloutMock Mock = new StaticResourceCalloutMock();
         mock.setStaticResource('AccountPostJobResp');
         mock.setstatusCode(200);
         mock.setStatus('OK');
         mock.setHeader('Accept', 'application/json');
         mock.setHeader('Content-Type', 'text/plain');
         test.setMock(HttpCalloutMock.class, Mock);
         AccountAPIToInsideviewRequest  ivapi = new  AccountAPIToInsideviewRequest();
         Database.executeBatch(ivapi, 1);

         /* ivTokenUtil test class execution*/  
         test.stopTest();    

Batch Class:

Global void Execute(Database.BatchableContext BC, List<sObject> scope)
{

    system.debug('Hello Execute');

    String CompanyIDs = '';

    List<String> ProcessedCIs = new List<String>();

    for (Sobject s : Scope)
    {        
     Account Act = (Account)s;
   /*  system.debug('Hello Execute and account:' + Act.NAME);*/

     CompanyIds += Act.Insideview_ID__c + ',' ;
     ProcessedCIs.add(Act.Insideview_ID__c);

    } 

    CompanyIds = CompanyIds.substring(0, CompanyIds.length() -1);          
    String EndpointURL = 'https://api.insideview.com/api/v1/company/job';
    string ivjobid = InsideviewPostJob.IVPostRequest(EndpointURL, CompanyIds);

Webservice Callout Class

Global class InsideviewPostJob{

    public static string IVPostRequest(String EndpointURL, String InsideViewIds) {
        String InsideviewJobId;
        System.debug('InsideViewIds: '+ InsideViewIds);
        if (InsideViewIds==null || InsideViewIds=='') {
            System.debug('No CompanyIds to send to Insideview API');
            return InsideviewJobId;
        }
        HttpRequest req = new HttpRequest();
        req.setEndpoint(EndpointURL);
        req.setMethod('POST');
        req.setHeader('accessToken', IVTokenUtils.getToken());
        req.setHeader('Accept', 'application/json');
        req.setheader('Content-Type', 'text/plain');
        req.setBody(InsideViewIds);
        system.debug('req.getBody():' + req.getBody());
        Http http = new Http();
        HttpResponse res = null;
        try {
            res = http.send(req);
        } catch(System.CalloutException e) {
            System.debug('Callout error: '+ e);
        }
        system.debug('PostJob-Resp: ' + res);
        if (res.getStatus()=='OK' && res.getstatuscode()==200) {
            String jsonData = res.getBody();
            System.debug('Post Response: '+ jsonData);
            InsideViewPostResp postResp = (InsideViewPostResp)JSON.deserialize(jsonData, InsideViewPostResp.class);

            if (postResp.jobId!=null) {
                InsideviewJobId = postResp.jobId;
            }
            return InsideviewJobId;
        }
       return InsideviewJobId;
    }
    }

Additional comment In above case, batchclass calls the future method and future method call the webservice class.

if I directly call the InsideviewPostJob from the test class, deployment works fine.

look at below test class that directly calls the webservice callout class.

@istest(seealldata=true)
public class InsideViewPostJob_Test {
    static testmethod void InsideViewPostJobTest(){


         //Create User
        User Usr = new User();
        Usr.Username = '[email protected]';
        Usr.LastName = 'x'; 
        Usr.Email = '[email protected]'; 
        Usr.Alias = 'testxxx'; 
        Usr.CommunityNickname = 'testxxxx';
        Usr.TimeZoneSidKey = 'America/New_York'; 
        Usr.LocaleSidKey = 'en_US'; 
        Usr.EmailEncodingKey = 'ISO-8859-1'; 
        Usr.ProfileId = ([select Id from Profile where name = 'iVH System Administrator'])[0].id;
        Usr.LanguageLocaleKey = 'en_us';
        Usr.iVH_Business_Unit__c = 'Adheris Health';
        insert usr; 

     system.runas(usr){
            test.startTest();
                StaticResourceCalloutMock Mock = new StaticResourceCalloutMock();
                mock.setStaticResource('PostJobResp');
                mock.setstatusCode(200);
                mock.setStatus('OK');
                mock.setHeader('Accept', 'application/json');
                test.setMock(HttpCalloutMock.class, Mock);
                string ivCompanyID = '12345';
                string EndpointURL = 'https://api.insideview.com/api/v1/company/job';     
                InsideviewPostJob.IVPostRequest(EndpointURL, ivCompanyID);
                InsideViewPostResp postResp = new InsideViewPostResp();
            test.stopTest();    
        } 

    }   

}
8
  • Is your test class using seealldata=true annotation or seealldata=false or nothing on the first line? If so, what version api is the test class? Between orgs there can be data differences, best practice being seealldata=false. Otherwise there could be a class or something missing in the deployment changeset to production that only test has? Could run a compare between orgs of the code-base too with eclipse. Jan 14, 2016 at 4:35
  • 1
    Are you also migrating the static resource along with the class? Jan 14, 2016 at 4:50
  • Did you look at the logs? Is the Catch block being hit. If so that would be the reason for res to be null. Does you batch class implement Database.allowsCallouts
    – Eric
    Jan 14, 2016 at 6:22
  • @MikeKatulka, Thanks for your response. Please look at my additional comment. i tried with seealldata=false and true, it is not working.. if test class directly calls the webservice callout class, deployment work fine... but when test class call the batchable class, batchable class calls the future method and future method call webservice callout.. it deployment fails.. looking forward for your help.
    – Razu
    Jan 15, 2016 at 14:06
  • @Eric, Thanks for your response. Please look at my additional comment. i tried with seealldata=false and true, it is not working.. if test class directly calls the webservice callout class, deployment work fine... but when test class call the batchable class, batchable class calls the future method and future method call webservice callout.. it deployment fails.. looking forward for your help. Yes, batchclass does have Database.allowCallouts
    – Razu
    Jan 15, 2016 at 14:07

1 Answer 1

0

Salesforcemarty,MkeKatulla,

Thanks for the response for my query. Your counter questions helped me in my analysis.

Finally it worked.

Here is the answer. In Fullcopy, webservice callout from schedulable/batch class works when you unit test (test class), if your try to deploy the same testclass fails.

Earlier code: in test class seealldata = false. few insert/update before test.startTest(). Between starttest() and stoptest(), I have put StaticResourceCalloutMock and called the batch class. It was giving error 'Pending work' during deployment. It works in fullcopy.

Working code in Test class seealldata = true. removed all insert/update before starttest() kept the code between starttest() and stoptest() as it is..

Now deployment works..

My understanding on having DML operation before starttest() was WRONG.

1
  • :) Great! My guess would be that your sandbox has been upgraded to Spring16 release. There is an obvious difference in behavior the way you had it. You seem to have figured out how to modify the code so it works in both places. Do you have the blue butterfly logo with 16 in the sandbox? If so, then production is an older release. In Spring16 I've been seeing a lot of changes around the unit tests, especially test.starttest and test.stoptest. Semi-related, code-base has changed: docs.releasenotes.salesforce.com/en-us/spring16/release-notes/… Jan 17, 2016 at 0:19

You must log in to answer this question.

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