Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a Controller (FooController) which calls an @future method (bar()) belonging to another class (FooServices).

Ideally in my test class for this Controller (FooControllerTest) I only want to test that the @future method has been called, I don't want to test its effects as that's FooServicesTest's job.

I know that I can use Test.startTest() and Test.stopTest() to see the effects of an @future method in a test class, but is there any way of identifying that a @future method has been called/queued up in a test class?

Since code is generally easier to understand than words, here is an example of what I would like to be able to do:


public class FooController
    public PageReference save()
        // Do some operations...

        // Call my @future method;

        return null;


public class FooServices
    public static void bar()
        // Do some things in the future...


private class FooControllerTest
    private static void save_ValidData_CalloutQueued()
        // Setup my test data...
        FooController controller = new FooController();;
        // Is this part possible? THE BELOW METHOD NAME IS ENTIRELY FICTIONAL
    // OR...
    private static void save_ValidData_CalloutExecuted()
        FooController controller = new FooController();
        // Yet another fictional method...

share|improve this question

The method looks like this:

static public Boolean isFutureRunning(System.Type type, String methodName) {
    String namespacePrefix;
    String name;

    if (type.getName().contains('.')) {
        //managed (namespaceprefix.classname)
        namespacePrefix = type.getName().substringBefore('.');
        name = type.getName().substringAfter('.');
    } else {
        //unmanaged (classname)
        namespacePrefix = '';
        name = type.getName();

    //find existing futures
    Integer existingFuturesCount = [
        SELECT COUNT()
        FROM AsyncApexJob
        WHERE ApexClass.NamespacePrefix = :namespacePrefix AND ApexClass.Name = :name
        AND MethodName = :methodName
        AND JobType = 'Future'
        AND Status IN ('Queued', 'Processing', 'Preparing')

    return existingFuturesCount != 0;
share|improve this answer
I'll give this a go when I'm back in the office, I'm assuming if I the Status clause I can pull out completed jobs? Is the AsyncApexJob table cleaned out between test methods or is it a 'system' style table where tests and your Org share the same data (like the RecordType table)? – Alex Tennant Jun 16 '14 at 18:13
@AlexTennant Yes, if you use startTest and stopTest the status should reach Complete. As for visibility, both real and test apex jobs will be seen. But your test jobs don't exist beyond each test method. I'm really lazy and just count them before and after, then look for n + 1 when asserting. – bigassforce Jun 16 '14 at 19:48
@AlexTennant I've just confirmed that in Test context, Future jobs don't appear in the table. Only Schedulable and Batchable ones. At least it works in real code... heh – bigassforce Jun 17 '14 at 10:19
Oh well... back to the drawing board. It's a useful piece of code to keep around for non-test situations though. – Alex Tennant Jun 17 '14 at 10:21
For now I've put an Idea on the Idea Exchange: – Alex Tennant Jun 17 '14 at 10:59


I love this question, as it's one of my pet peeves. People don't test @future calling methods because they don't know it's possible.

Enter the magic of two key methods:


When you utilize these methods -- and you should! they do a couple of key things for you.

  1. they reset your governor limits so you can test if your actual code is going to hit Limits.
  2. Test.StopTest(), actually forces your @future methods to run right now and return before progressing to the next step.

so, in your test example, if you take your exact test and add those two methods thusly:

private class FooControllerTest
    private static void save_ValidData_CalloutQueued()
        // Setup my test data...
        FooController controller = new FooController();
        // You can actually now assert that yes, it indeed was queued, 
        // and has run, and has returned data. Since this is a callout? 
        // look at the callout mocks for more info on returning mock 
        // data to assert on.


With Regards to just identifying of a job has been queued:

Select ApexClassId, CompletedDate, CreatedById, CreatedDate, ExtendedStatus, Id,
JobItemsProcessed, JobType, LastProcessed, LastProcessedOffset, MethodName, 
NumberOfErrors, ParentJobId, Status, TotalJobItems from AsyncApexJob

This object, (and query above) should list all pending async apex jobs including enqueued @future methods. I expect (but have never tried) that you could build a where clause based on MethodName. ApexClassId would likely work as well, but would be ugly as the Id's may be hard to come by dynamically.

share|improve this answer
Thanks for this, but as I started in the question I know that I can use startTest and stopTest to ensure the @future runs and then check the results. What I want is a way of checking if it has been run/queued without checking for any specific results (as the results of the call will be tested by another class specific to that). – Alex Tennant Jun 16 '14 at 18:11
@AlexTennant - My bad. I've added a bit at the end with a soql query that should help you get near what you want. – Kevin P Jun 16 '14 at 20:42
As noted in the comments on @user320's answer, Future jobs are not added to the ApexAsyncJob table in test contexts. I've added an Idea on the Idea Exchange for now: – Alex Tennant Jun 17 '14 at 11:02

With the newly available Queueable interface this problem becomes more approachable.

  1. replace your @Future annotated method with a Queueable inner class

  2. lean on Limits.getQueueableJobs() to count the jobs before and after


@IsTest public class QueueableTest {

    public class MyJob implements Queueable {
        public MyJob(String param1, String param2) {}
        public void execute(QueueableContext context) {}

    static testmethod void countMyJobs() {

        //this passes ok
        System.assertEquals(0, Limits.getQueueableJobs());

        //better than future
        Queueable job = new MyJob('param1', 'param2');

        //this also passes ok
        System.assertEquals(1, Limits.getQueueableJobs());


share|improve this answer
(the Queueable would be in your code... it's just inside the test here for brevity) – bigassforce Apr 28 '15 at 14:03

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.