LoginSignup
31
33

More than 5 years have passed since last update.

Apex テストクラス

Last updated at Posted at 2017-01-24

クラスの定義

SeeAllData=trueにすると既存のデータが参照できるようになるが、通常はfalseとする(ConnectAPIとか一部の機能はtrueじゃないと実行できないので注意)

@isTest(SeeAllData=false)
private class Ron_xxxControllerTest {

    @isTest 
    static void runProperties() {

    //testMethod の仕様は非推奨になっているため使わない。@isTestを使う
    public static testMethod void testXXX(){

テストメソッドの雛形

/*
 * target function:
 */ 
@isTest 
static void testXX() {
    //prepare user
    User u1 = TestUtil.createUser('test1');

    //execute and assert
    System.runAs(u1){
        //prepare test data

        //execute test
        Test.startTest();

        System.assertEquals(expected, actual);
        Test.stopTest();
    }
}

assert

System.assertEquals(期待値, 実際の値);
System.assert(評価の式);

テスト用にGETパラメータをセットする

ApexPages.currentPage().getParameters().put('xxxItemId', '');

start/end

startとstopをセットで使用すること。startとstopの間だけでガバナ制限がカウントされ、データ準備のためのコード実行分がカウントされない。

Test.startTest();
・・・
Test.stopTest();

runAs

特定のユーザーコンテキスト下でテストを実施する。

User u1 = createTestUser();
System.runAs(u1){
 ・・・
}

カスタム設定

SeeAllData=false環境下ではカスタム設定にもデータが設定されないことに注意。テストメソッド内でデータを準備する必要がある

public static xxx_Properties__c prepareCustomSettings(){
    xxx_Properties__c settings = new xxx_Properties__c();
    settings.Name = 'XXX';
    settings.email = 'aaa@aaa.com';
    insert settings;

    return settings;
}

VF拡張コントローラのテスト StandardController

//StandardControllerをnewして、コントローラに渡す
XX__c instance = new XX__c();
instance.xx__c = '123';
Apexpages.Standardcontroller sc = new Apexpages.Standardcontroller(instance);

XX_VF_Ctrl contl = new XX_VF_Ctrl(sc);

トリガーのValidationチェックのテスト(addError()を使うケース

try{
    insert c1;  //error
    System.assert(false); //例外が発生すべき
}catch(DmlException e)
}

テスト時に自動採番が増えないようにするオプション

[開発]-[Apexテスト実行]-[オプション]
「独立した自動採番順序」をチェックする
Screen Shot 2017-02-10 at 14.20.25.png

テストユーザーの作成コード

/*
 * create a test user
 *  name: firstName
 */
public static User createUser(String name){
    Profile profile = getStandardProfile();
    String profileId = profile.id;

    User user = new User();
    user.Email = name + 'test@xx.xxx.com';
    user.UserName = name + 'test@xx.xxx.com';
    user.FirstName = name;
    user.LastName = '123';
    user.Alias = user.UserName.split('@')[0].left(8);
    user.ProfileId = profileId;
    //user.UserRoleId = role.Id;
    user.EmailEncodingKey = 'ISO-2022-JP';
    user.LanguageLocaleKey = 'ja';
    user.LocaleSidKey = 'ja_JP';
    user.TimeZoneSidKey = 'Asia/Tokyo';
    insert user;
    user = [select Name, UserName, FirstName, LastName, Alias, UserRoleId, ProfileId, CreatedDate from user where UserName = :user.Username limit 1];

    return user;
 }

/*
 * get Profile of standard user
 */ 
public static Profile getStandardProfile(){
    Profile[] profiles;
    profiles =  [select Id From Profile where Name = '標準ユーザ' limit 1];
    if (profiles.isEmpty()){
       profiles =  [select Id From Profile where Name = 'Standard User' limit 1];
    }
    return profiles[0];
}

テスト実行時にprivateテストにアクセスできるようにする

@TestVisible を付ける

テスト実行時に特定のコードブロックを実行させないようにする

if (!Test.isRunningTest()) { 
    ....
}

MIXED_DML_EXCEPTIONの回避方法

UserやUserRoleに対するDMLとそれ以外のオブジェクトへのDMLを同じトランザクションで実行していることが理由。
説明

テストクラスでの回避方法はSystem.runAsを使用する

//use System.runAs block in order to avoid MIXED_DML_EXCEPTION
User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
System.runAs (thisUser){
    ....
}

Standard PriceBook IDの取得方法

テストクラスの中でPricebookEntry()を作成したい場合は、下記の間数で標準価格表のIDを取得する

Id pricebookId = Test.getStandardPricebookId();
PricebookEntry pbe = new PricebookEntry();
pbe.Product2Id = someProduct.Id;
pbe.Pricebook2Id = pricebookId;
pbe.UnitPrice = 0;
pbe.IsActive = true;
insert pbe;

31
33
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
33