5

Has anyone got an idea what could cause the following test to fail in one org and pass in another?

The error is System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out at Class.QueueableCalloutTest.QueueableCallout.execute: line 31, column 1

The orgs are both Partner Developer Orgs, from a single environment hub. Both have a namespace and are used for publishing packages.

I've checked the following settings are identical in setup

  • Apex Test Execution -> Options
  • Apex Settings
  • Critical Updates
  • User Interface

The failing test class:

@IsTest
public class QueueableCalloutTest {

    @IsTest static void testCallout() {

        Id profileId = [SELECT Id FROM Profile WHERE Name = 'Standard User'].Id;

        User u = new User(Alias = 'example', Email = 'exampletestuser@example.com', EmailEncodingKey = 'UTF-8', FirstName = 'Testing', LastName = 'Testing', LanguageLocaleKey = 'en_US', TimeZoneSidKey = 'Europe/London', LocaleSidKey = 'en_US', Username = 'exampletestuser@example.com', ProfileId = profileId);
        insert u;

        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());

        System.runAs(u) {

            Test.startTest();
            System.enqueueJob(new QueueableCallout());
            Test.stopTest();
        }
    }

    public class QueueableCallout implements Queueable, Database.AllowsCallouts {

        public void execute(QueueableContext ctx) {

            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://maps.googleapis.com');
            req.setMethod('GET');
            HttpResponse res = new Http().send(req);
        }
    }

    public class MockHttpResponseGenerator implements HttpCalloutMock {

        public HttpResponse respond(HttpRequest req) {

            HttpResponse res = new HttpResponse();
            res.setStatusCode(200);
            return res;
        }
    }
}

I think I've stripped it down to the bare minimum to reproduce the issue. The issue doesn't occur if the System.runAs call is removed. I understand that the System.enqueueJob() call counts as DML, but not why it might count as DML in one org and not another.

I've reviewed this Salesforce help article but I don't think it explains the discrepancy.

There are some posts here where people are getting this error, and they do point to workarounds which I'm aware I could implement, but none point to why there might be a discrepancy which is what I'd like to understand.

5
  • 2
    Enquejob is not the issue, I think some DMl is occurring before the callout, can you post the code in the QueueableCallout class? Feb 28 '20 at 12:55
  • Thanks Rahul. The QueueableCallout class is an inner class to QueueableCalloutTest - you should be able to paste that class into any org and run the test.
    – James
    Feb 28 '20 at 13:02
  • 1
    Does the failing org has any triggers on user object which performs a DML?
    – Raul
    Feb 28 '20 at 15:10
  • Thanks Raul. No, there's no trigger, process builder or workflow on the User object. Also, the test still fails in this org if I remove the line "insert u;" (but passes if I remove the insert statement and the System.runAs())
    – James
    Feb 28 '20 at 16:06
  • Have you tried running tests after you have "Disable Parallel Apex Testing" option checked? (you can find this option on Setup -> Apex Test Execution -> Options)
    – VarunC
    Feb 28 '20 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.