6

Situation


I have implemented an API to communicate with the external system. After 18th of August test that i have on production have started failing showing the infamous:

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

The weird thing is that those same tests are passing without any issues on the Sandbox, and as a matter of fact have been passing on Production until about two weeks ago. This is happening for all tests that have some sort of callouts happening after INSERT/UPDATE operations required to create the proper dataset for the test(s).

I have read the Performing DML Operations and Mock Callouts before and now so i can say i'm aware how these tests should be done (as said those tests are passing on the sandbox).

Pseudo code for tests:

DoTestDataSetup();//generate all records, insert them and do some updates if necessary
Test.setMock(HttpCalloutMock.class,new myMockImplementation());
Test.startTest();
      DoMyFutureMethodWithCallout();
Test.stopTest();

I know that the link I pasted says setMock() should be called inside the startTest() and I have tried it and got the same result.

Have there been some recent updates that could have affected this behavior?

IMPORTANT: code in production and in sandbox is completely the same i've done diff on them so the issue is not caused by code being invalid

  • I am planning to raise a case with SFDC for this. – zokito Sep 4 '14 at 9:55
  • Just to rule it out, are you using SeeAllData=true by chance? Have you looked at the Logs from running the test to see what DML operations are occurring? – Daniel Ballinger Sep 4 '14 at 10:13
  • No SeeAllData. Yes only the creation of my test data is happening - and associated triggers and WF rules. There are some send email rules but they occur after the callout when I update records statuses to error – zokito Sep 4 '14 at 10:20
  • 3
    If you can, pull the Apex Debug log down for the test from both the sandbox and production and then run them through a diff tool. Extra DML calls may indicate the cause. – Daniel Ballinger Sep 4 '14 at 10:22
  • Ok thanks I'll try that. I managed to comment out the failing parts of test without affecting the coverage severely, so deployments can be done to production. I have couple of them I need to take care of now and once that's taken care of ill update here with results. – zokito Sep 4 '14 at 10:25
1

I do have a general idea what might be wrong (see bottom of the answer), but more importantly I do want to write a general advice for when tests or code is suddenly failing. This has happened to me quite a bit already and these steps have helped me finding the issue.

Was it due to a Salesforce release? The first thing to check is whether a new Salesforce Release was rolled-out and whether that has impacted your code in a specific way. You should encounter your issue in Sandbox first, because those are upgraded to the newest release first, way before the Production instances are upgraded. In your case, you can rule out this possibility.

Was a Critical Update actived? From setup, search for 'critical updates' and you'll see a bunch of updates that are either activated or de-activated. Once an update is activated, that might have impact on your code. E.g. in your case if you were doing somePageReference.getContent(); that would count as a call-out after a specific update, but it would not count as a callout before that update was activated. So that's something you could check in your case.

Did somebody add a Validation rule or Process or Flow? These things can be added to Production without first going through a Sandbox, so this might take you by surprise. Imagine your Testcode created an Account without filling the Phone field, and suddenly a validation rule made it mandatory. Your tests will fail now. Or in your case, imagine a Flow was added that triggers some change in another record, which causes some Apex Trigger to perform a callout. This is something that's hard to control, but might influence your test code and/or other code significantly. Usually, the debug logs give you a good clue what's being executed, and where the error is coming from.

Did we hit some data-limit? Maybe your data has grown over e.g. 50.000 records so that when you perform a query, you will go over the 50.000 SOQL query limit. This is usually only a problem for actual live code, not for tests, unless of course you use the @SeeAllData annotation in your test classes.

In conclusion, for your situation, I can only think of an issue due to a Critical Update that was activated or some Process or Flow being added. As a suggestion, I would go through the debug logs and check for callouts and see if these are the ones that you'd expect.

  • 1
    Hi thanks for the very detailed answer - if you look at my latest comment on the question you'll see I nailed it down to flows, so in short you are correct and I'll accept the answer so it stays here for any future reference. – zokito Nov 22 '16 at 12:43

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.