
※この記事にはアフィリエイトリンクを含みます。
Test Data Factoryでテストデータ作成を固定できるようになると、次に詰まるのがここです。
「同期処理はテストできる。でも、非同期(Queueable/Batch)が絡むとテストが通らない」。
自分も最初は、テストメソッドの中でQueueableを投げて「動いたはずなのに検証ができない」状態になりました。
で、問題は、非同期は『実行タイミングをテスト側で握れない』ことなんですよね。
ってことで結論です。
結論:非同期処理のテストは『Test.startTest() と Test.stopTest() で実行タイミングを挟んで、止めるところまで見届ける』。
これが最小で一番堅い型です。
※ ここまで押さえたら次は、Queueable自体の動き(enqueueJob/実行順/制限)を知ると事故が減ります。
Contents
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で固定する
|毎回コピペをやめる最小テンプレ.png)
を-1ページで.png)
|毎回コピペをやめる最小テンプレ-300x169.png)
