0

I am having a custom button on my custom object, which calls a visualforce page by passing the record Id from which it was called. The controller for this Visualforce page is making a WebService Callout. I am facing issues while creating a test class for the same. I would need to create a record in my test class in order to be able to call the visualforce with the record Id. I have created a Mock response class as well.

But I am getting this error : System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

I know this is coming because I am performing the Web Service Callout immediately after performing a DML, in the same transaction. But that is what I am supposed to do while trying to cover the Apex code.

Is there any workaround for this?

Here is my test class code :

@isTest
private class SendRequesttoWebServiceControllerTest {
    @isTest static  void myTestMethod1() {
        String recordTypeforGulfport = '';
        List<RecordType> lstRecordTypeGulfport = [SELECT 
                                                            Id 
                                                   FROM 
                                                            RecordType 
                                                   WHERE 
                                                            SobjectType = 'Issue__c' 
                                                   AND 
                                                            DeveloperName = 'Gulfport'

                                                            limit 1]; 
        if(lstRecordTypeGulfport.size()>0){
            recordTypeforGulfport = lstRecordTypeGulfport[0].Id;
        }
        System.debug('Debug Log for record type'+recordTypeforGulfport);
        Issue__c objIssue1 = new Issue__c();
        objIssue1.RecordTypeId = recordTypeforGulfport;
        objIssue1.Sales_Order__c = '12345';
        insert objIssue1;

        Issue__c objIssue2 = new Issue__c();
        objIssue2.RecordTypeId = recordTypeforGulfport;
        objIssue2.Sales_Order__c = '12345';
        insert objIssue2;

        Test.setMock(HttpCalloutMock.class, new SendRequesttoWebServiceMock());
        ApexPages.currentPage().getParameters().put('id',objIssue1.id);
        SendRequesttoWebServiceController obj1 = new SendRequesttoWebServiceController();
        Pagereference pf1 = obj1.makeCallOut();
        ApexPages.currentPage().getParameters().put('id',objIssue2.id);
        Pagereference pf2 = obj1.makeCallOut();

    }  
}
  • 1
    Wrap the code at test.mock to the end in test.start and test.stoptest – Eric Nov 15 '17 at 9:09
  • @Eric, I tried that as well, but it didn't worked. – Shobhit Saxena Nov 15 '17 at 9:23
  • 2
    Then post what you did try. Because that’s what you need to do. – Eric Nov 15 '17 at 15:37
  • @Eric, I've used a future method instead to break the transactions. Doing so make my test to run successfully. – Shobhit Saxena Nov 16 '17 at 8:07
  • Seems you put the stop test right after the setmock. Test.stopTest should have been the last line of your code and that would have solved it. Sorry but your workaround is just wrong in so many ways. Had you posted what you tried we could have saved you some trouble. – Eric Nov 16 '17 at 14:22
-1

The main issue was that the DML for inserting records and the WebService callout were happening in the same transaction. So, the requirement was to split the transaction. So, I had to write another class with future method, that would be calling the WebService Callout portion of the main class.

The modified code, containing both the classed, is as follows :

@isTest
private class SendRequesttoWebServiceControllerTest {
    @isTest static  void myTestMethod1() {
        String recordTypeforGulfport = '';
        List<RecordType> lstRecordTypeGulfport = [SELECT 
                                                            Id 
                                                   FROM 
                                                            RecordType 
                                                   WHERE 
                                                            SobjectType = 'Issue__c' 
                                                   AND 
                                                            DeveloperName = 'Gulfport'

                                                            limit 1]; 
        if(lstRecordTypeGulfport.size()>0){
            recordTypeforGulfport = lstRecordTypeGulfport[0].Id;
        }
        System.debug('Debug Log for record type'+recordTypeforGulfport);
        Issue__c objIssue1 = new Issue__c();
        objIssue1.RecordTypeId = recordTypeforGulfport;
        objIssue1.Sales_Order__c = '12345';
        objIssue1.Container__c = '1232';
        insert objIssue1;

        Issue__c objIssue2 = new Issue__c();
        objIssue2.RecordTypeId = recordTypeforGulfport;
        objIssue2.Sales_Order__c = '12345';
        objIssue2.Container__c = '1232';
        insert objIssue2;

        List<Id> issueIds = new List<Id>();
        issueIds.add(objIssue1.Id);
        issueIds.add(objIssue2.Id);
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new SendRequesttoWebServiceMock());
        Test.stopTest();
        ValidationCallOut.doCallout(objIssue1.Id);
        ValidationCallOut.doCallout(objIssue2.Id);

    } 
    @isTest static  void myTestMethod2() {
        String recordTypeforGulfport = '';
        List<RecordType> lstRecordTypeGulfport = [SELECT 
                                                            Id 
                                                   FROM 
                                                            RecordType 
                                                   WHERE 
                                                            SobjectType = 'Issue__c' 
                                                   AND 
                                                            DeveloperName = 'Gulfport'

                                                            limit 1]; 
        if(lstRecordTypeGulfport.size()>0){
            recordTypeforGulfport = lstRecordTypeGulfport[0].Id;
        }
        System.debug('Debug Log for record type'+recordTypeforGulfport);
        Issue__c objIssue1 = new Issue__c();
        objIssue1.RecordTypeId = recordTypeforGulfport;
        objIssue1.Sales_Order__c = '12345';
        objIssue1.Container__c = '1232';
        insert objIssue1;

        Issue__c objIssue2 = new Issue__c();
        objIssue2.RecordTypeId = recordTypeforGulfport;
        objIssue2.Sales_Order__c = '12345';
        objIssue2.Container__c = '1232';
        insert objIssue2;

        List<Id> issueIds = new List<Id>();
        issueIds.add(objIssue1.Id);
        issueIds.add(objIssue2.Id);
        Test.startTest();
        Test.setMock(HttpCalloutMock.class, new SendRequesttoWebServiceMock2());
        Test.stopTest();
        ValidationCallOut.doCallout(objIssue1.Id);
        ValidationCallOut.doCallout(objIssue2.Id);

    } 

}

And another helper class having future method :

global class ValidationCallOut {
    @future(callout=true)
    public static void doCallout(Id recordId) {
        ApexPages.currentPage().getParameters().put('id',recordId);
        SendRequesttoWebServiceController obj1 = new SendRequesttoWebServiceController();
        Pagereference pf1 = obj1.makeCallOut();
    }
}
  • I don’t even know where to begin. Wrong – Eric Nov 16 '17 at 14:20

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.