2

I want to run the execute method of a Queueable Apex class

Why I want to do that:

To increase debugging speed. I want to anonymously call the method to avoid always enqueuing the job, going to setup --> Apex Jobs and see insufficient debug messages.

My Problem:

I fail to create an Instance of QueueableContext.

My current workaround:

Put all code in another method (which does need QueueableContext as Parameter) and call that method. However I feel there must be some easy way to directly call execute.

1
  • 1
    We can also do as the answers suggest for Schedulable and Batchable classes as well. A useful trick all-around.
    – sfdcfox
    Mar 23, 2023 at 18:00

2 Answers 2

4

I almost all cases, you can simply pass null into the queueable's execute() method.

e.g.

MyQueueable queueableInstance = new MyQueueable();

queueableInstance.execute(null);

If you actually do use the QueueableContext in your execute method, then it's an interface, and you can mock it.

public class MyQueueableContext implements QueueableContext{
    public Id getJobId(){
        // Not an async apex job id, but it is an Id and should thus work
        // Though if you do actually use the async job id, you'll need to adjust
        //   this
        return '001000000000000';
    }
}

MyQueueable queueableInstance = new MyQueueable();

queueableInstance.execute(new MyQueueableContext());
2
  • So easy, can't believe I did not consider this. Thanks!
    – Gerke
    Mar 23, 2023 at 17:30
  • 1
    N.B. if using fflib, getJobId() {return fflib_IDGenerator.generate(AsyncApexJob.SObjectType);} and then you could mock a selector to return AsyncApexJobs as sobjects
    – cropredy
    Mar 23, 2023 at 17:34
3

I've done this:

    private static Id fakeId(Integer n) {
        return AsyncApexJob.SObjectType.getDescribe().getKeyPrefix()
            + '000'
            + String.valueOf(n).repeat(9);
    }

    private static Id FAKE_JOB_ID = fakeId(1);

    private class FakeQueueableContext implements QueueableContext {
        public Id getJobId() {
            return FAKE_JOB_ID;
        }
    }

    /**
     * Allows chained Queueables in tests.
     */
    public static void enqueueJob(Queueable q) {
        if (!Test.isRunningTest()) {
            // Use real code
            System.enqueueJob(q);
        } else {
            // Use fake synchronous code
            synchronousEnqueueJob(q);
        }
    }

    private static void synchronousEnqueueJob(Queueable q) {
        QueueableContext qc = new FakeQueueableContext();
        q.execute(qc);
    }

You must log in to answer this question.

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