SOLUTION An object has workflow rule that sends an email and it was not mocked

EDIT I am simply trying to test future method that invokes SOAP service, but I get an exception.

EDIT 2 I have @testSetup method. If I comment it out, there is no exception. But Test.startTest() has to add new context to test, so no previous data can influence further execution?

class FutureClass {
    public static void invokeFuture() {
            Webservice.doSomeSOAPrequest(); // <- Exception appears at this line, this invokes webservice method.


class BikesWebserviceTest {
    static void testSomeWSOperations() {
        // No queries for now.
        Test.setMock(WebServiceMock.class, new BikeCalloutMock());

        FutureClass.invokeFuture(); // simply call future method that invokes SOAP service

        // no assertions for now

public class BikeCalloutMock implements WebServiceMock {
    public void doInvoke(
            Object stub,
            Object request_x,
            Map<String, Object> response_map_x,
            String endpoint,
            String soapAction,
            String requestName,
            String responseNS,
            String responseName,
            String responseType) {

        BikeWebservice.ResponseElement responseElement = new BikeWebservice.ResponseElement();
        responseElement.someField = 1;
        response_map_x.put('response_x', responseElement);
  • Is there any DML in BikeCalloutMock? Jun 10, 2016 at 15:58
  • @OlesMalkov no, it returns only an object the same as real webservice Jun 10, 2016 at 16:08
  • Then you probably need to set up a debug log and check all your DML there. Jun 10, 2016 at 16:12
  • you can also take a look at the Dan Appleman Advanced Apex 3rd edition chapter 7 pattern on async to see how a custom asyncRequest__c object and queueables can be used in a way that avoids this problem. Your future method will run into governor issues with bikes of size > 100. The Appleman pattern also solves this Limits issue.
    – cropredy
    Jun 11, 2016 at 1:08
  • @cropredy I have created mechanism to cut list every 100 elements, so I future will not get more that 100. Unfortunately I have only 1 edition of this book. Jun 13, 2016 at 10:28

2 Answers 2


It may work during live and record get updated but according to your code as posted you should be getting future methods cannot call future methods so I believe we do not have a clear picture of what is actually going on.

Your future updates the sObject which fires the trigger which calls the future again.

Try changing




Another thing to be aware of is that email alerts will cause the Uncommitted work pending error is test methods as well so check into those

Issue with Email Alerts and Test.setMock - Uncommitted Work Pending

  • I checked criteria for running future method, it runs only once. I can even remove dml update in future method, anyway an exception is thrown when calling out Jun 13, 2016 at 14:29
  • According to what u posted it runs twice. Check for email alerts as well. See the link I posted
    – Eric
    Jun 13, 2016 at 14:34
  • You were correct, my apologies, I just did not read attentively your last lines of answer Jun 15, 2016 at 17:01

the problem is that you are performing a DML which will fire a @future which will fire a callout.

In normal world that would be 2 separate transactions - DML in sync Apex and Callout in @future context.

However, in test, it is 1 transaction, therefore this exception is thrown.

you can refer to this article about MOCKS after DML in test, but the problem is, you are performing DML and a callout in one single line.

update bike;

The only way to avoid exception to be thrown in this particular scenario is, probably, use test.isrunningtest() in your actual class, block callout method call in test context, call it in test directly after data is set.

  • Please have a look at edit 1 Jun 13, 2016 at 12:59
  • read the article about MOCKS and DML I mentioned, it directly describes your situation. Also, try to check for limits after test.stoptest() I think you need to disable future execution for test context and/or disable callout itself with help or test.isrunningtest() and than call it directly, as described in article.
    – Andrei.Z
    Jun 13, 2016 at 15:51

You must log in to answer this question.

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