1

Here is the scenario I'm running into. Is there any way to unit test a rollback where dml is performed followed by an async process? I understand that wrapping savepoint in if(!Test.isRunning()) is the workaround but obviously cannot test rollback functionality.

The error is thrown: System.CalloutException: You have already created Savepoints. You cannot make callout after creating a Savepoint

public static void foo() {
    Savepoint savePoint = Database.setSavepoint();
    try { 
        performLogic();
        insertRecords();
        updateRecords();

        //regular callout is not allowed here
        //future and queuable Apex is allowed
        asyncQueuableApexWithCallout();
    } 
    catch (Exception ex) {
        logEvent();
        Database.rollback(savepoint);
        throw new Exception();
    }
}

Test.startTest();
foo();
Test.stopTest();

0

If you want to test rollback in your code sample, your testmethod needs to inject testdata such that either:

  • performLogic() throws an exception
  • insertRecords() " "
  • updateRecords() " "

Since such an exception will occur before the callout attempt, the catch block will be executed.

Now how you inject such an exception is dependent on your application. For example, inserting an Account without a Name will throw an exception.

Normally, one uses dependency injection via a constructor arg to do this kind of stuff but you can also set @TestVisible static variables that the code-under-test uses to get values from to do work. The testmethod would set the @testVisible variable to some value that will cause an exception to be thrown (e.g. null, -1, etc -- it all depends)

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.