Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
Salesforce Developer
hard

How do you write tests for async Apex (@future, Queueable, Batch)?

Async testing requires careful use of Test.startTest() and Test.stopTest() to force async work to run synchronously inside the test.

Pattern:

`apex @isTest static void testAsync() { Account acc = new Account(Name='Test'); insert acc;

Test.startTest(); MyClass.doFutureWork(acc.Id); // async work queued Test.stopTest(); // <-- async work runs HERE, synchronously

Account refreshed = [SELECT Phone FROM Account WHERE Id=:acc.Id]; System.assertEquals('updated', refreshed.Phone); } `

Key rules:

  • `Test.startTest()` resets governor limits for the test code that follows. Useful for isolating limit usage.
  • `Test.stopTest()` flushes async work@future, Queueable, Batch jobs queued during the test all execute synchronously when stopTest is called.
  • Without stopTest, async work doesn't run during the test; you can't assert on its effects.

Specifics by async type:

`@future`:

  • Test calls the future method between startTest/stopTest. The work runs at stopTest.
  • Cannot test future call from within another future (Salesforce restriction).

Queueable:

  • Same pattern. The Queueable's execute() runs synchronously at stopTest.
  • For chained Queueables: only the FIRST chain link runs in the test. Subsequent links require additional test-method invocations or the chain is mocked.

Batch Apex:

  • Same pattern, but the test must process records you've inserted.
  • start() returns the QueryLocator (or iterable); test setup must populate the source records.
  • execute() runs once per chunk. In tests, the entire query result becomes one chunk regardless of batch size — keep test data small.
  • finish() runs at the end.

Common pitfalls:

  • Forgetting Test.stopTest() — async never runs, assertions fail.
  • Trying to chain Queueables in test — can't easily test deep chains.
  • Querying for the result before stopTest — async hasn't run yet, results are stale.
  • Not setting up enough test data to make assertions meaningful.

Mocking external callouts in async tests:

  • Use Test.setMock(HttpCalloutMock.class, new MyMock()) — works in async too.

The async test pattern is one of the most common interview questions and most common production-code mistakes.

Why this answer works

Senior. The startTest/stopTest mechanism and the chained-Queueable testing limit are the strongest signals.

Follow-ups to expect

Related dictionary terms