Memos About Salesforce

Salesforceにハマってたこと!

salesforce バッチ テストクラス executeメソッドカバ率ない?

f:id:jude2016:20190920155743j:plain

こんにちは、管理人の@Salesforce.Zです。

バッチクラスを書きました。Executeメソッドはカバ率なし。なぜ???

今回、バッチのexecuteメソッドのテストを実行できるようにするため、すこし共有したいと思います。

読んだら得ること

★ バッチクラスのexecuteメソッドをテストする方法

目次

バッチクラス

大量処理をするとか、時刻を設定し、その時刻になったら、自動実行させるとか、というようなことがバッチで、できます。

バッチクラスの構成

バッチを作るには、Database.Batchable インターフェースを実装が必要な次の 3 つのメソッドが含まれています。

・startメソッド(バッチ実行するには1回のみ動作する)

・executeメソッド(複数回に分けて処理する、データ量をバッチサイズで割って、その回数で実行する処理)

・finishメソッド(バッチ実行するには1回のみ動作する)

startメソッド

インターフェースメソッド execute に渡すレコード or オブジェクトを収集するには、Apex バッチの冒頭で start メソッドをコールします。このメソッドは、Database.QueryLocator オブジェクト、or ジョブに渡すレコードやオブジェクトが含まれる Iterable オブジェクトを返します

global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}

executeメソッド

データの処理単位ごとに必要な処理を実行するには、execute メソッドを使用します

global void execute(Database.BatchableContext BC, list<P>){}

finishメソッド

処理しましたよ、のような通知を行うことがここで、よくやります。

global void finish(Database.BatchableContext BC){}

バッチクラスのテストクラス

global with sharing class YourBatch implements Database.Batchable<sObject> {
    /*
    * バッチ処理開始時に最初に呼び出される
    * バッチ処理対象のレコードを返却するQueryLocatorを返す
    */ 
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String query = 'SELECT ** FROM XX';
        return Database.getQueryLocator(query);
    }

    /*
    * バッチサイズで指定されたレコード数単位で executeが呼び出される
    *  targetRecords: 対象となるレコード
    */
    global void execute(Database.BatchableContext bc, List<sObject> targetRecords) {
        // 処理
    }

    /*
    * バッチ処理の終了時に呼び出される
    * 終了処理を実装する
    */
    global void finish(Database.BatchableContext bc) {
        // 処理
    }
}

バッチクラスのexecuteメソッドをテストする

@isTest
private class YourBatchTest {
    // 実行ユーザ
    private static User adminUser = Common.executeAdminUser();

    
    private static testMethod void batchTest(){
        ServiceProperty__c sp = TestDataUtil.createServiceProperty(true);
        ServiceOpportunity__c so = TestDataUtil.createServiceOpportunity(false, sp);
        so.SalesDueDate__c = Date.today();
        so.RecordTypeId = CreateSnapshotWithServiceOppBatch.recTypeMap.get(CreateSnapshotWithServiceOppBatch.snapshotRecdType).Id;
        insert so;

        YourBatch batchable = new YourBatch();

        System.runAs(adminUser) {
            Test.startTest();
            // バッチを開始
            Database.QueryLocator ql = batchable.start(null);
            
            // バッチを実行
            batchable.execute(null, youPreparedDataList);//you can set here List<sObject>, instead start method query result pass to here

            // バッチを終了
            batchable.Finish(null);
            
            
            Test.stopTest();
        }
    }
}

終わりに

すこし、無理やり、対象メソッドを実行したですね^^

Apex の一括処理の使用