14

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.

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

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
}
  • 4
    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 '17 at 20:56
  • Alexander, @AdrianLarson, Test class is working now, Thanks for your help :) – Devendra Jun 29 '17 at 21:10

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.