31

I have two Queueable classes, I am trying to execute them by chaining them. First approach was to calling second queueable from first class.

But, it gives me System.AsyncException: Maximum stack depth has been reached. error in test class.

My Apex classes version is 40.0

Class 1:

public with sharing class QueueableClass1 implements Queueable{
    public QueueableClass1(){}

    public void execute(QueueableContext context){}
}

Class 2:

public with sharing class QueueableClass2 implements Queueable{
    public QueueableClass2(){}
    public void execute(QueueableContext context){}
}

Method: The following execution works, but I am looking for chaining queueable jobs.

public void processQueues(){
    System.enqueueJob(new QueueableClass1());
    System.enqueueJob(new QueueableClass2());
}

Below code gives "System.AsyncException: Maximum stack depth has been reached." error in test class.

public with sharing class QueueableClass1 implements Queueable{
    public QueueableClass1(){}

    public void execute(QueueableContext context){
        System.enqueueJob(new QueueableClass2());    
    }
}

Test Class: The test class has following syntax.

@isTest
public class MyClass_Test {

    @testSetup
    static void createData(){
        // created sample data       
    }
    
    static testMethod void test_processQueues() {
        
        Test.startTest();
        MyClass obj = new MyClass();
        obj.processQueues(); // This method consist of first Queueable Job. And Second Job has been chained into the first job
        Test.stopTest();
    }
}

Just wanted to know, Am I doing anything wrong here? I am looking for execution of second class when first class has finished its operation.

4
  • Is the error only specific to Test class ?Do you receive error in actual class ? Jun 29, 2017 at 20:40
  • 2
    can you provide test class too ? Jun 29, 2017 at 20:41
  • @MohithShrivastava This error is specific to test class. Actual class is working as expected.
    – Devendra
    Jun 29, 2017 at 20:52
  • 2
    I think Alexander has the answer for you .Looks like apex test does not support this . Jun 29, 2017 at 20:53

1 Answer 1

41

The next lines on salesforce documentation about Queueable interface say the following

You can’t chain queueable jobs in an Apex test. Doing so results in an error. To avoid getting an error, you can check if Apex is running in test context by calling Test.isRunningTest() before chaining jobs.

So to test funcionality you can simulate chaining:

QueueableClass1 first = new QueueableClass1();
first.execute(null);
//Asserts go here
QueueableClass2 second = new QueueableClass2();
second.execute(null);
//Asserts go here

Do not run code above between Test.startTest() and Test.stopTest(), as this will cause to do a try of chaining second class (and this will result in error)

according to Adrian's suggestion about Test.isRunningTest() add testvisible Boolean field, that allow you to have flexible control of behavior of class:

public with sharing class QueueableClass1 implements Queueable{
    @testVisible
    private static Boolean doChainJob = true;

    public QueueableClass1(){}

    public void execute(QueueableContext context){
        if(doChainJob) {
            System.enqueueJob(new QueueableClass2());    
        }
    }
}

Then to test it without Test.isRunningTest()

@isTest
static void testFirstQueueable(){
    QueueableClass1.doChainJob = false;
    Test.startTest();
        System.enqueueJob(new QueueableClass1());
    Test.stopTest();
    //Asserts goes here
}
2
  • 10
    I tend to prefer a @TestVisible static Boolean flag to control this sort of behavior for a bit more flexibility. Though I just avoid calling Test.isRunningTest() if it's even remotely possible.
    – Adrian Larson
    Jun 29, 2017 at 20:56
  • Alexander, @AdrianLarson, Test class is working now, Thanks for your help :)
    – Devendra
    Jun 29, 2017 at 21:10

You must log in to answer this question.

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