Skip to main content

Apex トリガーをテストする

学習の目的

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

  • 単一レコード操作を起動するトリガーのテストを記述する。
  • クラスのすべてのテストメソッドを実行する。
メモ

メモ

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

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

Apex トリガーをテストする

トリガーをリリースする前に、トリガーを起動するアクションを実行し、結果が予想どおりであることを確認する単体テストを記述します。

「Apex トリガー」モジュールで取り上げたトリガーをテストしましょう。取引先レコードに商談が関連付けられている場合、AccountDeletion トリガーはレコードが削除されるのを防ぎます。

前提条件

まだ AccountDeletion トリガーを追加していない場合は、次の手順に従います。

  1. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Trigger (Apex トリガー)] をクリックします。
  2. トリガー名に「AccountDeletion」と入力して、sObject に [Account (取引先)] を選択します。[送信] をクリックします。
  3. デフォルトのコードを次のコードに置き換えます。
    trigger AccountDeletion on Account (before delete) {
      // Prevent the deletion of accounts if they have related opportunities.
      for(Account a : [SELECT Id FROM Account
        WHERE Id IN (SELECT AccountId FROM Opportunity) AND
        Id IN :Trigger.old]) {
        Trigger.oldMap.get(a.Id).addError('Cannot delete account with related opportunities.');
      }
    }

前の単元で AccountDeletion トリガーを追加し、システムで問題をチェックできるように無効化してある場合は、再び有効にします。

  1. [Setup (設定)] から 「Apex Triggers 」 (Apex トリガー) を検索します。
  2. [Apex Triggers (Apex トリガー)] ページで、AccountDeletion トリガーの横にある [Edit (編集)] をクリックします。
  3. [Is Active (有効)] を選択します。
  4. [保存] をクリックします。

前の単元で取り上げた AddRelatedRecordCalloutTrigger、または HelloWorldTrigger というトリガーが組織にある場合は、無効にします。たとえば、AddRelatedRecord トリガーを無効にする手順は、次のとおりです。

  1. [Setup (設定)] から 「Apex Triggers 」 (Apex トリガー) を検索します。
  2. [Apex Triggers (Apex トリガー)] ページで、AddRelatedRecord トリガーの横にある [Edit (編集)] をクリックします。
  3. [Is Active (有効)] をオフにします。
  4. [保存] をクリックします。

HelloWorldTrigger トリガーと CalloutTrigger トリガーを無効にするには、上記の手順を繰り返します。

単体テストを追加し、実行する

最初に、テストメソッドを追加してみましょう。このテストメソッドでは、トリガーが設計された目的 (ポジティブケース) を検証します。つまり、取引先に商談が関連付けられている場合はその取引先が削除されないようにします。

  1. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] をクリックします。
  2. クラス名として「TestAccountDeletion」と入力し、[OK] をクリックします。
  3. デフォルトのクラス本文を次のコードで置き換えます。
    @isTest
    private class TestAccountDeletion {
      @isTest
      static void TestDeleteAccountWithOneOpportunity() {
        // Test data setup
        // Create an account with an opportunity, and then try to delete it
        Account acct = new Account(Name='Test Account');
        insert acct;
        Opportunity opp = new Opportunity(
          Name=acct.Name + ' Opportunity',
          StageName='Prospecting',
          CloseDate=System.today().addMonths(1),
          AccountId=acct.Id);
        insert opp;
        // Perform test
        Test.startTest();
          Database.DeleteResult result = Database.delete(acct, false);
        Test.stopTest();
        // Verify
        // In this case the deletion should have been stopped by the trigger,
        // so verify that we got back an error.
        System.assert(!result.isSuccess());
        System.assert(result.getErrors().size() > 0);
        System.assertEquals('Cannot delete account with related opportunities.',
          result.getErrors()[0].getMessage());
      }
    }
    このテストメソッドでは最初に、商談のあるテスト取引先を設定します。次に、このテスト取引先を削除すると、この操作によって AccountDeletion トリガーが実行されます。テストメソッドで、Database.delete() コールの戻り値をチェックして、トリガーによってテスト取引先の削除が防止されたことを確認します。戻り値の Database.DeleteResult オブジェクトには、削除操作に関する情報が含まれます。テストメソッドで、削除が行われなかったことと、エラーメッセージが取得されたことを確認します。
  4. このテストを実行するには、[Test (テスト)] | [New Run (新規実行)] をクリックします。
  5. [Test Classes (テストクラス)] の下で、[TestAccountDeletion] をクリックします。
  6. TestAccountDeletion クラスのすべてのメソッドをテスト実行に追加するには、[Add Selected (選択項目を追加)] をクリックします。
  7. [実行] をクリックします。[Tests (テスト)] タブの最新の実行で、テスト結果を見つけます。

TestAccountDeletion テストクラスには、1 つの取引先レコードをテストする 1 つのテストメソッドのみが含まれます。また、このテストはポジティブケースが対象です。商談のない取引先の削除や取引先の一括削除など、必ず他のシナリオもテストして、すべてのケースでトリガーが機能することを確認します。

テストデータはテストメソッド内部に設定されるため、さらにテストメソッドを追加していくと、設定に時間がかかる場合があります。多くのテストメソッドがある場合は、テストデータの作成をテストユーティリティクラスに入れて、複数のテストメソッドからそのユーティリティクラスをコールします。次の単元では、テストユーティリティクラスを利用して、さらにいくつかのテストメソッドを追加する方法ついて説明します。

もうひとこと...

テストメソッドには、Test.startTest() メソッドと Test.stopTest() メソッドのペアが含まれます。このペアによって、ガバナ制限の最新セットを取得するコードのブロックが区切られます。このテストでは、テストを実行する前に、テストデータの設定に 2 つの DML ステートメントが使用されます。その Apex コードがガバナ制限内で実行されることをテストするには、データ設定の使用制限をテストの使用制限と切り離す必要があります。データ設定プロセスの使用制限を切り離すには、テストコールを Test.startTest()Test.stopTest() のブロックで囲みます。このテストブロックは、非同期 Apex をテストする場合にも使用します。詳細は、「Limits、startTest、および stopTest の使用」を参照してください。

メモ

開発者コンソールの既知の問題により、テストのサブセットを実行した場合はコードカバー率が正しく更新されません。コードカバー率の結果を更新するには、[Test (テスト)] | [New Run (新規実行)] ではなく、[Test (テスト)] | [Run All (すべて実行)] を使用します。

リソース

ハンズオン Challenge の準備をする

この単元のハンズオン Challenge を完了するには、以下のコードを使用して RestrictContactByName という名前の Contact オブジェクトに Apex トリガーを作成する必要があります。

trigger RestrictContactByName on Contact (before insert, before update) {

  //check contacts prior to insert or update for invalid data

  for(Contact c : Trigger.New) {

    if(c.LastName == 'INVALIDNAME') {

      //invalidname is invalid

      c.AddError('The Last Name "'+c.LastName+'" is not allowed for DML');

    }

  }

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

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

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