Test fails with runAs, queueable and callout in specific org

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.

Answer

Attribution
Source : Link , Question Author : James , Answer Author : Community

Leave a Comment