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
sai sekhar 1sai sekhar 1 

You have uncommitted work pending. Please commit or rollback before calling out.(Trailhead superbadges)

Hi ,

The below test class and it is  throwing an error :System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

@isTest
private class ProjectCalloutServiceTest {
    //Implement mock callout tests here

    @testSetup static void testSetupdata(){
        //create the opportunity record
        Opportunity opp1 = new Opportunity();
        opp1.Name = 'sai Corp1';
        opp1.Type = 'New Project';
        opp1.Amount = 200;
        opp1.CloseDate = Date.today();
        opp1.StageName = 'Submitted Project';
        insert opp1;
        //create the opportunity record
        Opportunity opp2 = new Opportunity();
        opp2.Name = 'sai Corp2';
        opp2.Type = 'New Project';
        opp2.Amount = 150;
        opp2.CloseDate = Date.today();
        opp2.StageName = 'Resubmit Project';
        insert opp2;
        //create the Custom Settings
        ServiceTokens__c servToken = new ServiceTokens__c();
        servToken.Name = 'ProjectServiceToken';
        servToken.Token__c = '67bac2a8-61b5-4f5b-9dda-51de3b18369a';
        insert servToken;
    }
    
    @isTest static void testPostCalloutSuccess() {
        Opportunity opp = [Select Id, Name FROM Opportunity WHERE Name = 'sai Corp1' Limit 1];
        List<Id> oppList = new List<Id>();
        oppList.add(opp.Id);
        System.assertEquals('sai Corp1', opp.Name);
        System.assertEquals(1,oppList.size());
        Test.startTest();
        // Set mock callout class 
        Test.setMock(HttpCalloutMock.class, new ProjectCalloutServiceMock()); 
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        ProjectCalloutService.postOpportunityToPMS(oppList);
        // Verify that the response received contains fake values
        Test.stopTest();    
        opp = [select StageName from Opportunity where id =: opp.Id];
        System.assertEquals('Submitted Project',opp.StageName);
    }
    
    @isTest static void testPostCalloutFailure() {
        Opportunity opp = [Select Id, Name FROM Opportunity WHERE Name = 'sai Corp2' Limit 1];
        List<Id> oppList = new List<Id>();
        oppList.add(opp.Id);
        System.assertEquals('sai Corp2', opp.Name);
        System.assertEquals(1,oppList.size());
        Test.startTest();
        // Set mock callout class 
        Test.setMock(HttpCalloutMock.class, new ProjectCalloutServiceMockFailure()); 
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        ProjectCalloutService.postOpportunityToPMS(oppList);
        // Verify that the response received contains fake values
        Test.stopTest();        
        opp = [select StageName from Opportunity where id =: opp.Id];
        System.assertEquals('Resubmit Project',opp.StageName);
    }
    
}

public class ProjectCalloutService {
    
    //method to be invoked by ProcessBuilder apex
    @InvocableMethod
    public static void postOpportunityToPMS(List<Id> oppoIds){
        Opportunity opportunity = [SELECT Id,Name,Account.Name,CloseDate,Amount FROM Opportunity WHERE Id = :oppoIds[0]];
        String serviceToken = ServiceTokens__c.getValues('ProjectServiceToken').Token__c;
        String jsonInput = '{\n' +
            ' "opportunityId" : "'+opportunity.Id+'",\n'+
            ' "opportunityName" : "'+opportunity.Name+'",\n'+
            ' "accountName" : "'+opportunity.Account.Name+'",\n'+
            ' "closeDate" : "'+String.ValueOf(opportunity.CloseDate).mid(0,10)+'",\n'+   
            ' "amount" : "'+opportunity.Amount+'"\n}';
        System.enqueueJob(new QueueablePMSCall(serviceToken, jsonInput, opportunity.Id));
    }
    
    // future method to make apex callout
    @Future(callout=true)
    private static void postToPMS(String serviceToken, String jsonInput, Id oppoId) {
            HTTPRequest req = new HTTPRequest();
            req.setEndPoint('callout:ProjectService');
            req.setMethod('POST');
            req.setHeader('token',serviceToken);
            req.setHeader('Content-Type', 'application/json;charset=UTF-8');        
            req.setBody(jsonInput);
            HTTP http = new HTTP();
            HTTPResponse res = http.send(req);
            Opportunity opp = new Opportunity(Id=oppoId);
            if(res.getStatusCode() != 201){
                opp.StageName = 'Resubmit Project';
                System.debug('Failure: ' + res.getStatusCode() + ' ' + res.getStatus());
            } else {
                opp.StageName = 'Submitted Project';                
                System.debug('Success: ' + res.getStatus());
            }
            update opp;
    }
    
    //queueable class to enque the post request
    class QueueablePMSCall implements System.Queueable, Database.AllowsCallouts {
        private String serviceToken;
        private String jsonInput;
        private String Id;
        public QueueablePMSCall(String serviceToken, String jsonInput, Id oppoId){
            this.serviceToken = serviceToken;
            this.jsonInput = jsonInput;
            this.Id = oppoId;
        }
        public void execute(QueueableContext context) {
            postToPMS(serviceToken, jsonInput, Id);
        }
    }
    
}
v varaprasadv varaprasad
Hi Sai,

More Info on this check once below link : 

https://success.salesforce.com/answers?id=9063A0000019WRGQA2

Hope this helps you.


Thanks
Varaprasad
@For Support: varaprasad4sfdc@gmail.com
 
sai sekhar 1sai sekhar 1
@varaoprasad the main class is working only test class is failing i have checked that link.But it didn't resolve the issue.