【Salesforce】Test.startTest/stopTestとは?Queueable/Batchをテストする最小パターン

※この記事にはアフィリエイトリンクを含みます。

Test Data Factoryでテストデータ作成を固定できるようになると、次に詰まるのがここです。

「同期処理はテストできる。でも、非同期(Queueable/Batch)が絡むとテストが通らない」。

自分も最初は、テストメソッドの中でQueueableを投げて「動いたはずなのに検証ができない」状態になりました。

で、問題は、非同期は『実行タイミングをテスト側で握れない』ことなんですよね。

ってことで結論です。

結論:非同期処理のテストは『Test.startTest() と Test.stopTest() で実行タイミングを挟んで、止めるところまで見届ける』。

これが最小で一番堅い型です。

※ ここまで押さえたら次は、Queueable自体の動き(enqueueJob/実行順/制限)を知ると事故が減ります。

次に読む
非同期テストの次は「Queueable自体の基本」です。 enqueueJobの動き方、実行順、よく踏む制限をまとめました。
【Salesforce】Queueableの基本(enqueueJob/実行順/制限)を読む →

Test.startTest/stopTestは何をしている?

ざっくり言うと、テストの中で『本番っぽい実行区間』を切り出すための仕組みです。

  • Test.startTest() で「ここからが本番区間」という印を付ける
  • Test.stopTest() で「キューに積まれた非同期処理をここで実行させる」

なので、QueueableやFutureなどの非同期は、基本的に stopTest() のタイミングで動きます。

(実行順や詳細はケースによりますが、まずこの理解でOKです)

最小パターン:Queueableをテストする

ここでは、イメージしやすいように「取引先のフラグを立てるQueueable」を例にします。

例:Queueable(テスト対象

public class AccountFlagQueueable implements Queueable {
private Id accountId;

public AccountFlagQueueable(Id accountId) {
this.accountId = accountId;
}

public void execute(QueueableContext context) {
Account a = [SELECT Id, Description FROM Account WHERE Id = :accountId];
a.Description = 'Done';
update a;
}
}

テスト(最小)

@IsTest(SeeAllData=false)
public class AccountFlagQueueableTest {

@IsTest
static void testQueueable() {
// 1) データ準備(Factoryでも直書きでもOK)
Account a = new Account(Name = 'Test Account');
insert a;

// 2) 非同期実行を挟む
Test.startTest();
System.enqueueJob(new AccountFlagQueueable(a.Id));
Test.stopTest();

// 3) 検証(stopTest後なら反映されている)
Account after = [SELECT Description FROM Account WHERE Id = :a.Id];
System.assertEquals('Done', after.Description);
}
}

この順番が崩れると、だいたい詰まります。

  • enqueueJob は startTest と stopTest の間に置く
  • 検証(SELECT/assert)は stopTest の後に置く

よくある詰まりポイント(ここだけ押さえる)

1) stopTestの前に検証してしまう

非同期がまだ走っていないので、検証が失敗します。

対策:検証は stopTest の後。

2) テストデータが足りない(必須項目・参照関係)

非同期が動く前に落ちているケースです。

対策:Test Data Factoryで「よく使う形」を固定する(この記事の前段)。

3) Queueableの中で別の非同期を呼んでいる

ネストした非同期は、想定通りに追えないことがあります。

対策:まずは「非同期は1段」に落としてテストを作り、必要なら設計を分ける。

Batchをテストする最小パターン(入口だけ)

Batchも考え方は同じで、『startTest/stopTestで挟む』が基本です。

@IsTest(SeeAllData=false)
public class SampleBatchTest {

@IsTest
static void testBatch() {
// データ準備
// (必要ならFactoryで作る)

Test.startTest();
Database.executeBatch(new SampleBatch(), 200);
Test.stopTest();

// 検証:stopTest後に結果を確認
}
}

Batchは「どのデータが対象になるか」「実行後に何が更新されるか」を検証に落とすのが要点です。

(ここは対象ロジックごとに変わるので、まずは型だけ固定すると楽です)

まとめ

  • 非同期(Queueable/Batch)のテストは『startTest/stopTestで挟む』のが基本
  • enqueueJob / executeBatch は startTest と stopTest の間に置く
  • 検証は stopTest の後に置く
  • データ作成が散らかるなら、先にTest Data Factoryで固定する

おすすめの記事