0

I have a before update trigger which makes a future callout. When i am writing the test class for it, i am updating the object in test method to achieve coverage for trigger. However this is causing error in test class execution and error says - "You have uncommitted work pending. Please commit or rollback before calling out."

Now i know i can't do dml before callout but without dml my trigger wont fire. I am not sure what i am missing here. Any suggestion will be much appreciated.

Thanks

Trigger Snippet:

if(opp.stageName = 'Gained Commitment' && more conditions) 
{
    if(HelperClass.firstRun){
        // So that trigger dont fire twice 
        HelperClass.firstRun=false;
        List<Opportunity> op = new List<Opportunity>();
        op.add(Trigger.newMap.get(opportunityId));
        op[0].Commitment_Call_Type__c = 'Amount above threshold';
        op[0].Commitment_Lock__c = True;
        // future method called from below class *********
        SAPInterfaceCommitmentManager.sendOpportunity(op);
    }
}

Future webservice callout from above trigger:

@future(callout = true)
public static void SAPInterfaceCommitmentCallout (string JSON, ID id, String CallType) {
    // Webservice callout . . . 
}

Test Method:

static testMethod void unitTest1() {
    
    Test.startTest();
    Test.setMock(HttpCalloutMock.class, new MockTokenResponseSucess());
    Account acc = [select id from account where SAP_SoldTo_ID__c = :SAP_ID ];
    opportunity opp = [select id,Is_Proforma_Editable__c,SoldTo_Account_Credit_Block_Reason__c,Available_Credit_Acc_Curr__c,Opportunity_Total_Fees__c,Last_Credit_Check_Time__c from opportunity where SoldTo_Account__c=:acc.id ];
    opp.stageName = 'Gained Commitment';
    update opp;
    system.debug('opportunity values'+opp);
    Test.stopTest(); 
}
3
  • Providing the code and test class that you have right now would probably be helpful. The only thing that I can think of is that you're trying to work around the @future callout and end up calling it synchronously. If you're not using Test.startTest() and Test.stopTest(), you likely should be.
    – Derek F
    Commented Dec 4, 2020 at 20:42
  • Sorry, wanted to keep it short so didn't put entire code. Basically dml and callout is being happening in single transaction.
    – Sara
    Commented Dec 4, 2020 at 22:08
  • Did you tag @future(callout = true) to your static method sendOpportunity in the SAPInterfaceCommitmentManager class? I only see a SAPInterfaceCommitmentCallout method with the future annotation.
    – Chun
    Commented Dec 5, 2020 at 0:28

1 Answer 1

1

The trigger code calls a sendOpportunity(op) method in the SAPInterfaceCommitmentManager class. But I only see a SAPInterfaceCommitmentCallout method with the future annotation. Either call this method or tag sendOpportunity(op) with @future.

You must log in to answer this question.

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