ApexTriggerの基本の型

By | September 10, 2021

前書き

ApexTriggerの基本の型をご紹介します。

今回ご紹介する型はTrigger Frameworkを利用していないいわば初心者向けの内容となっており、がっつり作り込む予定がある場合は下記のようなApexTriggerフレームワークの利用を推奨します。

■ApexTriggerフレームワーク

flexible-apex-trigger(※アクセンチュア推奨)

 上記の解説サイト(日本語)

SFDC trigger framework(※Salesforce推奨)

 上記に関連したTrailhead(英語)

 上記の日本語の解説サイト(日本語)

Triggerクラスの書き方

ポイント↓

最上部には必ずコメントを残しましょう。

コード内にもコメントを残すとよりベターです。

・Trigger内には具体的な処理を記載せずにhandlerクラスを呼び出すようにしましょう。

見本↓

/*******************************************************************************************
* @CopyRight    Eherenfest. Inc.
* @CreatedDate  2021/09/01
* @Description  取引先のApexTrigger
* @Author      りがるでぃ
* @Modification Log
Ver Date       Author     Modification
1.0 2021/09/05 りがるでぃ forLoop内にSOQLを記述していた問題を修正
*******************************************************************************************/

trigger AccountTrigger on Account (after insert) {  
    AccountTriggerHandler handler = new AccountTriggerHandler();
    if (Trigger.isAfter) {
        if (Trigger.isInsert) {
            //社名変更を営業部チャンネルに通知
            handler.notifyCompanyNameChange(Trigger.new);
        }
    }
}

Handlerクラスの書き方

ポイント↓

最上部には必ずコメントを残しましょう。

各メソッドの前にも必ずコメントを残しましょう。より複雑なクラスの場合は、引数(param)と戻り値(return)についても必ずコメント内に記載してください。

共有ルールの適用(with sharingやwithout sharing)は必ず明示的に記載してください。

定数はクラス内に記述せずに、定数クラスを利用してください。

見本↓

/*******************************************************************************************
* @CopyRight    Eherenfest. Inc.
* @CreatedDate  2021/09/01
* @Description  取引先のHandler。社名変更時にSlackチャンネルに自動通知するメソッドを実装済み。
* @Author      りがるでぃ
* @Modification Log
Ver Date       Author     Modification
1.0 2021/09/05 りがるでぃ 投稿先のチャンネルが誤っていた問題を修正
1.1 2021/09/07 りがるでぃ 開発用に記述していたsystem.debugを削除
*******************************************************************************************/

public with sharing class AccountTriggerHandler {

//コンストラクタ
    public AccountTriggerHandler() {        
    }    
    
//営業部Slackチャンネルに社名変更を通知 
    public void notifyCompanyNameChange(List<Account> accList) {
    String SlackBotName = Constants.SLACK_BOT_NAME;
        //以降の具体的な処理     
    }  
}

Constantsクラスの書き方

ポイント↓

最上部には必ずコメントを残しましょう。

・各定数の前に、何に関する定数なのか必ずコメントで記載してください。

final修飾子を利用して定数宣言を行ってください。

見本↓

/*******************************************************************************************
* @CopyRight    Eherenfest. Inc.
* @CreatedDate  2021/09/01
* @Description  定数クラス。
* @Author      りがるでぃ
* @Modification Log
*******************************************************************************************/

public with sharing class Constants{
    // 注文.状況:Draft
    public static final String DRAFT_STATUS =  'Draft';
    // 注文.状況:Activated
    public static final String ACTIVE_STATUS = 'Activated';    
    //SlackBot名 
    public static final String SLACK_BOT_NAME  = 'ねこ';
    //HTTPステータスコード:200
    public static final Integer STATUS_OK = 200;
    //HTTPステータスコード:201
    public static final Integer STATUS_CREATED = 201;    
}

Testクラスの書き方

ポイント↓

最上部には必ずコメントを残しましょう。

・下記の構成を遵守しましょう。

testSetupアノテーション付きのメソッド内でテストデータを作成

②isTestアノテーションを付けたメソッド内の、Test.startTest()の前でテストデータを準備

③ isTestアノテーションを付けたメソッド内の、Test.startTest()とTest.stopTest()の間でテストメソッドを実行

④ isTestアノテーションを付けたメソッド内の、Test.stopTest()の後でAssertを利用して結果検証

・ApexTriggerやApexClassを複数利用する見込みがある場合は、(下記の見本のようにはせずに)TestDataFactoryを利用しましょう。

見本↓

/*******************************************************************************************
* @CopyRight    Eherenfest. Inc.
* @CreatedDate  2021/09/01
* @Description  テストクラスforAccountTrigger&AccountTriggerHandler
* @Author      りがるでぃ
* @Modification Log
*******************************************************************************************/


@isTest
private class AccountTriggerTest {

    @testSetup
    private static void testDataFactory(){
        //取引先レコードを作成
        Account acc = new Account(
            Name = 'MyCompany'
        );
        insert acc;
    }

    @isTest
    static void insertAccount(){
        
        //取引先レコードを取得
        List<Account> accList = [SELECT Id,Name FROM Account LIMIT 1];
        Account aRecord = accList[0];        
        
        Test.startTest();
        //取引先レコードを作成
        Account acctoinsert = new Account(
            Name = aRecord.Name
        );        
        insert acctoinsert;       
        Test.stopTest();
    }

    Account queriedacc = [SELECT Id,Name FROM Account WHERE Id =: acctoinsert.Id];
    System.assertEquals(queriedacc.name,"MyCompany");
}

TestDataFactoryクラスの書き方

ポイント↓

最上部には必ずコメントを残しましょう。

・同一オブジェクトに関して属性の異なる複数のレコードが必要な場合は、(下記の見本のようにはせずに)属性を動的に変更することが可能なメソッドを作成しましょう。

見本↓

/*******************************************************************************************
* @CopyRight    Eherenfest. Inc.
* @CreatedDate  2021/09/01
* @Description  TestDataFactory
* @Author      りがるでぃ
* @Modification Log
*******************************************************************************************/

@isTest
public with sharing class AccountTriggerTest {

  //リード
    public static Lead createLead(Boolean doInsert){
        Lead newLead = new Lead() ;
        newLead.FirstName = 'Taro';
        newLead.LastName = 'Yamada';
        newLead.Company = 'TestCompany';
        if(doInsert){
            insert newLead;
        }
        return newLead;
    }
  
  //取引先
    public static Account createAccount(Boolean doInsert){
        Account acc = new Account();
        acc.Name = 'TestAccount';
        if(doInsert){
            insert acc;
        }
        return acc;
    }
}