Skip to main content
Slack の Trailblazer Community がオープンベータを開始しました。ぜひ参加して、リアルタイムで交流しましょう。Slack に参加する

Apex テストのテストデータを作成する

学習の目的

この単元を完了すると、次のことができるようになります。

  • テストユーティリティクラスを作成する。
  • テストユーティリティメソッドを使用してさまざまなテストケースのテストデータを設定する。
  • クラスのすべてのテストメソッドを実行する。
  • テストユーティリティクラスを使用して、テストデータ設定のために再利用可能なメソッドを追加します。
メモ

メモ

日本語で受講されている方へ
Challenge は日本語の Trailhead Playground で開始し、かっこ内の翻訳を参照しながら進めていってください。Challenge での評価は英語データを対象に行われるため、英語の値のみをコピーして貼り付けるようにしてください。日本語の組織で Challenge が不合格だった場合は、(1) この手順に従って [Locale (地域)] を [United States (米国)] に切り替え、(2) [Language (言語)] を [English (英語)] に切り替えてから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしてみることをお勧めします。

翻訳版 Trailhead を活用する方法の詳細は、自分の言語の Trailhead バッジを参照してください。

前提条件

前の単元の「Apex トリガーをテストする」の前提条件の操作を完了します (まだ完了していない場合)。

テストユーティリティクラスを追加する

テストデータ作成をユーティリティクラスメソッドへのコールに置き換えて、前のテストメソッドをリファクタリングしましょう。最初に、テストユーティリティクラスを作成する必要があります。

TestDataFactory クラスは、@IsTest アノテーションが付加された公開クラスで、実行中のテストからのみアクセスできます。テストユーティリティクラスには、テストメソッドからコールしてテストデータの設定などの便利なタスクを実行できるメソッドが含まれます。テストユーティリティクラスは、組織のコードサイズ制限から除外されます。

TestDataFactory クラスを追加する手順は、次のとおりです。

  1. Web コンソールで、Ctrl+Shift+P (Windows) または ⌘+Shift+P (macOS) を押してコマンドパレットを開きます。
  2. SFDX: Create Apex Class (SFDX: Apex クラスを作成) と入力し、Enter キーを押します。
  3. テンプレートの種別に [DefaultApexClass] を選択し、Enter キーを押します。
  4. クラス名に TestDataFactory と入力し、Enter キーを押します。
  5. 出力ディレクトリに [force-app/main/default/classes] を選択し、Enter キーを押します。
  6. デフォルトのクラス本文を次のコードで置き換えます。
@IsTest
public with sharing class TestDataFactory {
  public static List<Account> createAccountsWithOpps(Integer numAccts, Integer numOppsPerAcct) {
    List<Account> accts = new List<Account>();
    for(Integer i=0;i<numAccts;i++) {
      Account a = new Account(Name='TestAccount' + i);
      accts.add(a);
    }
    insert as user accts;
    List<Opportunity> opps = new List<Opportunity>();
    for(Integer j=0;j<numAccts;j++) {
      Account acct = accts[j];
      // For each account just inserted, add opportunities
      for(Integer k=0;k<numOppsPerAcct;k++) {
        opps.add(new Opportunity(Name=acct.Name + ' Opportunity ' + k,
          StageName='Prospecting',
          CloseDate=System.today().addMonths(1),
          AccountId=acct.Id));
      }
    }
    // Insert all opportunities for all accounts.
    insert as user opps;
    return accts;
  }
}

このテストユーティリティクラスには 1 つの静的メソッド createAccountsWithOpps() が含まれます。このメソッドは取引先数 (numAccts パラメーターに保持) と取引先ごとに作成する関連商談数 (numOppsPerAcct パラメーターに保持) を受け入れます。メソッドの最初のループでは、指定された数の取引先を作成し、accts リスト変数に保存します。最初のループの後、insert DML ステートメントがコールされて、リスト内のすべての取引先をデータベース内に作成します。

2 つ目のループでは商談を作成します。各商談グループは、1 つの取引先にリンクしているため、外部ループは取引先を反復処理し、その中にネストされたループでは、現在の取引先の関連商談を作成します。次回ネストループが実行されるとき、add() メソッドを使用して商談が同じリストに追加されます。商談は、AccountId 項目を使用して親取引先にリンクされます。作成されるすべての商談の合計数は、商談数と取引先数の積 (numOppsPerAcct*numAccts) になります。次に、insert DML ステートメントをループ外で効率的にコールし、すべての取引先についてコレクション内のすべての商談を 1 回のコールのみで作成します。

最後に、このメソッドは新規取引先のリストを返します。

Note

このメソッドでは関連商談は返されませんが、それらのレコードを取得するには、「Apex トリガーのテスト」のトリガーで使用したクエリのような、Account と Opportunity 間の既存のリレーションを利用する SOQL クエリを作成します。

テストデータ作成用のユーティリティメソッドをコールする

テストユーティリティクラスを追加したところで、次はこのクラスを利用するように TestAccountDeletionテストクラスを変更します。TestDataFactory.createAccountsWithOpps(1,1) コールから返される配列には 1 つの Account sObject が含まれます。

変更されたテストメソッドは次のようになります。

@IsTest
private with sharing class TestAccountDeletion {
  @IsTest
  static void TestDeleteAccountWithOneOpportunity() {
    // Test data setup
    // Create one account with one opportunity by calling a utility method
    Account[] accts = TestDataFactory.createAccountsWithOpps(1,1);
    // Perform test
    Test.startTest();
      Database.DeleteResult result = Database.delete(accts[0], false, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify that the deletion should have been stopped by the trigger,
    // so check that we got back an error.
    Assert.isFalse(result.isSuccess());
    Assert.isTrue(result.getErrors().size() > 0);
    Assert.areEqual('Cannot delete account with related opportunities.',
      result.getErrors()[0].getMessage());
  }
}

さまざまな条件でテストする

トリガーに対して可能性のあるすべての入力をテストするには、1 つのテストメソッドでは不十分です。商談のない取引先が削除される場合など、他の条件もテストする必要があります。また、1 件のレコードだけでなく、大量のレコードで同じシナリオをテストする必要もあります。3 つのテストメソッドが追加されたテストクラスの更新バージョンを次に示します。この更新バージョンのクラスを保存します。

@IsTest
private with sharing class TestAccountDeletion {
  @IsTest
  static void TestDeleteAccountWithOneOpportunity() {
    // Test data setup
    // Create one account with one opportunity by calling a utility method
    Account[] accts = TestDataFactory.createAccountsWithOpps(1,1);
    // Perform test
    Test.startTest();
      Database.DeleteResult result = Database.delete(accts[0], false, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify that the deletion should have been stopped by the trigger,
    // so check that we got back an error.
    Assert.isFalse(result.isSuccess());
    Assert.isTrue(result.getErrors().size() > 0);
    Assert.areEqual('Cannot delete account with related opportunities.',
      result.getErrors()[0].getMessage());
  }
  @IsTest
  static void TestDeleteAccountWithNoOpportunities() {
    // Test data setup
    // Create one account with no opportunities by calling a utility method
    Account[] accts = TestDataFactory.createAccountsWithOpps(1,0);
    // Perform test
    Test.startTest();
      Database.DeleteResult result = Database.delete(accts[0], false, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify that the deletion was successful
    Assert.isTrue(result.isSuccess());
  }
  @IsTest
  static void TestDeleteBulkAccountsWithOneOpportunity() {
    // Test data setup
    // Create accounts with one opportunity each by calling a utility method
    Account[] accts = TestDataFactory.createAccountsWithOpps(200,1);
    // Perform test
    Test.startTest();
      Database.DeleteResult[] results = Database.delete(accts, false, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify for each record.
    // In this case the deletion should have been stopped by the trigger,
    // so check that we got back an error.
    for(Database.DeleteResult dr : results) {
      Assert.isFalse(dr.isSuccess());
      Assert.isTrue(dr.getErrors().size() > 0);
      Assert.areEqual('Cannot delete account with related opportunities.',
        dr.getErrors()[0].getMessage());
    }
  }
  @IsTest
  static void TestDeleteBulkAccountsWithNoOpportunities() {
    // Test data setup
    // Create accounts with no opportunities by calling a utility method
    Account[] accts = TestDataFactory.createAccountsWithOpps(200,0);
    // Perform test
    Test.startTest();
      Database.DeleteResult[] results = Database.delete(accts, false, AccessLevel.USER_MODE);
    Test.stopTest();
    // For each record, verify that the deletion was successful
    for(Database.DeleteResult dr : results) {
      Assert.isTrue(dr.isSuccess());
    }
  }
}

すべてのテストメソッドを実行する

最後のステップでは、テストクラスのテストメソッドを実行します。クラスはより包括的なテストが含み、テストデータファクトリを使用するようにリファクタリングされています。

  1. Web コンソールで、アクティビティバーにある テストアイコン をクリックします。[Testing (テスト)] サイドパネルが開きます。
  2. [Testing (テスト)] 検索バーに TestAccountDeletion と入力します。
  3. クラスのすべてのテストメソッドを実行するには、TestAccountDeletion の行にカーソルを置き、テスト実行アイコン をクリックします。
  4. [Test Results (テスト結果)] パネルで結果を確認します。テスト実行で 4 つのテストがすべて合格したとレポートされます。

リソース

Salesforce ヘルプで Trailhead のフィードバックを共有してください。

Trailhead についての感想をお聞かせください。[Salesforce ヘルプ] サイトから新しいフィードバックフォームにいつでもアクセスできるようになりました。

詳細はこちら フィードバックの共有に進む