Developer

テストクラスのベストプラクティス【セールスフォース】

Developer
この記事は約4分で読めます。

こんにちは、アンダーソンです。
今回は上級デベロッパーで出てきた問題を元に、改めてテストクラスの
ベストプラクティスを考えていきたいと思います。

Testクラスで使えるオブジェクト

今回試験でこのような問がありました。
Testクラスで(SeeAllData=false)だとアクセスできないオブジェクトはどれですか。

  • User
  • Profile
  • Report
  • RecordType

・Report

正解できましたか?
基本的にはTestクラスからは組織のデータにアクセスできないのですが、一部例外があります。

  • User
  • Profile
  • Organization
  • AsyncApexJob
  • CronTrigger
  • RecordType
  • ApexClass
  • ApexTrigger
  • ApexComponent
  • ApexPage

上記のデータへはそのままアクセスできます。さらにIsTest(SeeAllData=true)をクラスまたはメソッドに付加することで無効にすることができます。

また、テストメソッドからトリガを呼び出すような処理があったとしても組織のデータにアクセスできない場合は失敗になるなど、細かい要件もありますので、しっかり抑えておきましょう。

データを作成する

組織のコントローラやクラスが多くなるにつれて、その分テストクラスも増えていってしまうかと思います。その分メソッドも多くなり、リリースの際に時間がかかってしまう原因となってしまいます。
全てのテストクラス内でデータを用意するのは時間のかかる原因となってしまうので、
テストデータは読み込み、もしくは共通のユーティリティクラスを作成してしまいましょう。

テストデータの読み込みは下記のように静的リソースから呼び出します。
オブジェクトタイプを指定し、リソース名をStringで指定すればOKです。

List<sObject> ls = Test.loadData(Account.sObjectType, 'myResource');

次にユーティリティクラスでは、AccountやContactなどの組織でよく使うものを汎用的に作成する
@isTestがついたテストクラスです。
例えば下記のような形が推奨されています。

TestDataFactoryUtilCls

@isTest
public class TestDataFactory {
    public static void createTestRecords(Integer numAccts) {
        List<Account> accts = new List<Account>();
        
        for ( Integer i=0 ; i < numAccts ; i++ ) {
            Account a = new Account(Name = 'TestAccount' + i);
            accts.add(a);
        }
        insert accts;
}

上記のようにテストクラスですが他からの呼び出しがあるため、public装飾子であることに注意しましょう。(もしくはglobalです。)
このようにしておけばテストコンテキストでの実行時に呼び出すことができます。
ほかのテストクラスからの呼び出しは通常のメソッドの呼び出し方と同じです。

Test.startTest()とTest.stopTest()

このメソッドで囲むことによってコードのガバナ制限をリセットしてくれます。
聞こえはいいのですが単純に、その中で行われるテストでのガバナ制限をチェックする機能だと
考えましょう。

startTestが始まるとそれまでのガバナ制限にたいしてリミットが加えられますが、stopTestによって元の状態に戻ることも頭に入れておきましょう。

System.runAs()を使う

Apexコードはシステムモードで実行されるため、レコードの共有などの確認を行うことができない場合にこのメソッドを使ってレコード共有の強制実行を行うことができます。
使い方はメソッドをブロックで囲み、ブロック内で実行するコードの記述をします。

Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
User u = new User(Alias = 'newUser', Email='test@test.com',
EmailEncodingKey='UTF-8', LastName='Test', LanguageLocaleKey='en_US',
LocaleSidKey='en_US', ProfileId = p.Id, UserName='newuser@testorg.com');
System.runAs(u){
   //実行するコードを記述
}

まとめ

他にもできることはありますが、上級デベロッパー試験対策としては問題ないかと思います。
綺麗で無駄のないテストクラスを書くのも技術の内ですね。
しっかり腕を磨いていけるように頑張ります。

その他の開発に関する記事はこちらです。

Developerも含めた試験問題にチャレンジしてみましょう。

コメント