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.

5
  • 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, 2014 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, 2014 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, 2014 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, 2014 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, 2015 at 6:00

1 Answer 1

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());
2
  • I should have said I already tried that, and it did not work. Nevertheless thanks.
    – GoldenAxe
    Jul 5, 2014 at 14:13
  • @GoldenAxe which API version is the class? Jul 16, 2015 at 6:11

You must log in to answer this question.

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