1

Error: You have uncommitted work pending. Please commit or rollback before calling out.

Problem: I have a callout request which works only if I don't inserting an opportunity before it in test class.

In the following example I'm inserting an opportunity to reproduce the error, while actually not doing anything with the opportunity, in my real test I use the opportunity as a parent of an SObject I'm testing, and the VF controller is querying for fields of the opportunity parent, so if the opportunity is not inserted the controller won't be able to preform most of it logic, and test coverage will be low.

Small example as possible to reproduce the error:

@isTest
private class aaa_TestMockCallByPass {
    @isTest static void test_mockCall_bypass() 
    {
        Opportunity opp = new Opportunity(Name='testOpp', StageName='Close gagnée', CloseDate=Date.today());
        // This does not work!
        insert opp;

        // This works - but it is a bad solution since the Id is relative to current salesforce org.
        // Give opportunity a real Id from the system, and using upsert seems to work,
        // meaning I have an opportunity to query from in the scope data of the test.
        //opp.Id = '006L0000004WRDc';
        //upsert opp;

        Test.startTest();
        //Set mock callout, to by pass test class limit, which prevent callout from test classes.
        Test.setMock(HttpCalloutMock.class, new mockHttpResponseGenerator());
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://api.salesforce.com/foo/bar');
        req.setMethod('GET');
        Http h = new Http();
        HttpResponse res = h.send(req);
        Test.stopTest();
    }
}

Note: that this error only happens when inserting Opportunity, I have tested insertion of other objects (Account, Contact, custom objects,...), and all works.

  • 1
    does the insert of the Opportunity invoke a trigger that does a callout? Your test setup is odd as why would you do a httpcallout in the code within Test.startTest()...Test.stoptest() - the mock is there to provide a fake response from the callout executed by whatever is being tested – cropredy Jul 5 '14 at 21:03
  • It's to show my code that produce the real callout does not relate to the real problem, hence I make the callout inside the test, to show myself that when not inserting an opportunity before it does invoke the mockcallout. The opportunity have only triggers related to the Custom Quote Sync (Managed) package, which I can't see, because it is manged package. – GoldenAxe Jul 5 '14 at 21:14
  • forgive my confusion...perhaps if you posted the original testmethod that was giving you issues with the uncommitted work error. Also -- is it possible that the underlying code does two callouts and you need to use MockMultiple? – cropredy Jul 5 '14 at 21:20
  • Let me try to rephrase, my original code is irrelevant, because as you can see even with the above simple test I got the error. The only code that not related to mine and can invoke somthing on opportunity is managed package. – GoldenAxe Jul 5 '14 at 21:28
  • If there are any email alerts that get sent during the transaction is will cause this error.....salesforce.stackexchange.com/questions/71259/… – Eric Dec 2 '15 at 6:00
0

Try putting this line before the test.StartTest section instead of within it. I can't remember why that can work, but I think it is because you need it set before actions within the starttest fire

Test.setMock(HttpCalloutMock.class, new mockHttpResponseGenerator());
| improve this answer | |
  • I should have said I already tried that, and it did not work. Nevertheless thanks. – GoldenAxe Jul 5 '14 at 14:13
  • @GoldenAxe which API version is the class? – bigassforce Jul 16 '15 at 6:11

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.