0

I have created class and test class. I got an error like this

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out :Class.Searchaddress.restapi: line 59, column 1 Class.Searchaddress_test.Testsearchaddress: line 20, column 1

but it displays 81%.how to rectify this error? please help me

Class:

global class Searchaddress {

public String accName{get;set;}
public String StNumber{get;set;}
public String Bcity{get;set;}
public String BPostalcode{get;set;}
public String BCountry{get;set;}
public Id accId{get;set;}
string Id;
list<Account>updateAdd=new list<Account>();

public Searchaddress(ApexPages.StandardController controller) {
 id=ApexPages.currentPage().getParameters().get('id');
 }

public PageReference autosave(){

    for(Account updatelist:[SELECT id,BillingAddress,BillingCity,BillingCountry,BillingLatitude,BillingLongitude,BillingPostalCode,BillingState,BillingStreet FROM Account where id=:id]){
        updatelist.BillingStreet=StNumber;
        updatelist.BillingCity=Bcity;
        updatelist.BillingPostalCode=BPostalcode;
        updatelist.BillingState='';
        updatelist.BillingCountry=BCountry;
        updateAdd.add(updatelist);
      }


    update updateAdd;
    PageReference pageRef = new PageReference('/' + ApexPages.currentPage().getParameters().get('id')+'?inline=0');
    return pageRef;
    }


public class Properties
    {
        public String city;
        public String label;
        public String id;
        public String postcode;
        public String name;
        public String citycode;
        public String context;
        public Double score;
        public String type;

    }


 @RemoteAction
global static list<String> restapi(string accName){

        string jsonStr; 

        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setHeader('Accept','application/JSON');
        req.setEndpoint('http://api-adresse.data.gouv.fr/search/?q='+ EncodingUtil.urlEncode(accName,'UTF-8'));//+'&'+'limit'+'='+'10');//
        req.setMethod('GET');
        HttpResponse res = h.send(req);
        system.debug('res)===>'+res);
        system.debug('res.getBody()===>'+res.getBody().replace('\n', ','));
        List<String> calOut = new List<String>();
        jsonStr= res.getBody();
        system.debug('res1===>'+res.getBody());
        JSONParser parser = JSON.createParser(jsonStr);

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

          JSON2Apex parsed = JSON2Apex.parse(res.getBody());
          for (JSON2Apex.Features f : parsed.Features)
          {
              JSON2Apex.Properties p = f.Properties ;

               // calOut1.add(p.label+ ', ' + p.context+ ',' + p.city+ ', ' + p.postcode);
              calOut1.add(p.label+' '+'FRANCE');


          }
          return calOut1;
          }
    }

Test class:

@isTest
public class Searchaddress_test {
    static testMethod void Testsearchaddress() {
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        Account testAccount = new Account(Name='sample demo',Rfleet_DueDate_Period1__c = '4',Hello__c='sdf', Number_Of_Locations__c=5.67, Sales_Rep__c='samplled');
        insert testAccount;
        testAccount.BillingStreet='chengalpattu';

        update testAccount;
        Account myTestTrainee = [SELECT id From Account LIMIT 1];
        PageReference myVfPage = Page.Searchaddress;
        system.test.setCurrentPage(myVfPage);

        ApexPages.currentPage().getParameters().put('id', myTestTrainee.id);//Pass Id to page
        ApexPAges.StandardController sc = new ApexPages.StandardController(myTestTrainee);
        Searchaddress apextestclass=new Searchaddress(sc);
        apextestclass.autosave();
         String jsonStr ='Base Product';
        Searchaddress.restapi(jsonStr);


         }

}

Callout class:

public class CalloutClass {
    public static HttpResponse getInfoFromExternalService() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://api-adresse.data.gouv.fr/search/q='+'france');
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        return res;
    }
}
3
  • Can you include the full error message. All we can tell at the moment is that an error was thrown while executing this line HttpResponse res = h.send(req);
    – BarCotter
    Commented Aug 19, 2015 at 12:05
  • @BarCotter,error: (System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out)
    – kiran k
    Commented Aug 19, 2015 at 12:12
  • 3
    There are a lot of questions on here for that issue. Have a look through them to see if they answer your question
    – BarCotter
    Commented Aug 19, 2015 at 12:16

2 Answers 2

1

You need to set the start and stop test properly:

@isTest
public class Searchaddress_test {
    static testMethod void Testsearchaddress() {
        Account testAccount = new Account(Name='sample demo',Rfleet_DueDate_Period1__c = '4',Hello__c='sdf', Number_Of_Locations__c=5.67, Sales_Rep__c='samplled');
        insert testAccount;
        testAccount.BillingStreet='chengalpattu';

        update testAccount;
        Account myTestTrainee = [SELECT id From Account LIMIT 1];
        PageReference myVfPage = Page.Searchaddress;
        system.test.setCurrentPage(myVfPage);

        ApexPages.currentPage().getParameters().put('id', myTestTrainee.id);//Pass Id to page
        ApexPAges.StandardController sc = new ApexPages.StandardController(myTestTrainee);
        Searchaddress apextestclass=new Searchaddress(sc);
        apextestclass.autosave();
         String jsonStr ='Base Product';

        Test.startTest(); //after all the dml
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());

        Searchaddress.restapi(jsonStr); //call you method that makes callout
        Test.stopTest();

         }

}

Also of note:

In addition to the comments above and answers below, if you have a workflow email alert on an object being inserted then properly do your callout (wrapping in test.starttest()) you will get the uncommitted work pending error as well..... See this question.answer: Issue with Email Alerts and Test.setMock - Uncommitted Work Pending

0

The general cause of the issue is a Web Service Callout may not occur after a DML statement within the same transaction ... reference

This shouldn't happen in the context of test class if you surround your web service call only (not dml operations) with system.startTest and system.stopTest (because this guarantees all DML operations are completed before the web service call). However, we encountered a situation that the test class gave the same error. I raised a case with Salesforce and the marked this as known issue. As per the article, this should be resolved in winter 16 release.

You must log in to answer this question.

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