function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
kyasukyasu 

Batchクラスのテストが、startで止まってしまいます。

こんにちは


現在、次のようなバッチクラスのテストメソッドを作成しています。


BatchClass:

global class BatchClass implements Database.Batchable<sObject> {
	public String query = 'Select c.Id, c.Name, From CustomObject__c c;

	global Database.QueryLocator start(Database.BatchableContext bc) {
        	return Database.getQueryLocator(query);
        } 
........

}

BatchClassTest:

 

 public class BatchClassTest {
    static testMethod void testBatch() {         
        CustomObject__c co = new CustomObject__c(Id = 'id', Name = 'name');   

        BatchClass bc = new BatchClass();
        bc.query = 'Select c.Id, c.Name From CustomObject__c c Limit 200;
        Test.startTest();
        Database.executeBatch(bc, 200);
        Test.stopTest();
    }
}

 

しかし、作成したものを、「テストを実行」するとexecute以降が読まれません。

 

デバッグログには、以下のようなことが書かれていました。


デバッグログ:

No more than one executeBatch can be called from within a testmethod. Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.

 


色々と似たような例を探したのですが、なかなか糸口が見つかりません。

どうすれば、execute以降も読まれるようになるのでしょうか。
お願い致します。

kyasukyasu

すみません

insertが抜けていました

テストクラスは以下になります。

 

 

public class BatchClassTest {
    static testMethod void testBatch() {         
        CustomObject__c co = new CustomObject__c(Id = 'id', Name = 'name');   

	insert co;

        BatchClass bc = new BatchClass();
        bc.query = 'Select c.Id, c.Name From CustomObject__c c Limit 200;
        Test.startTest();
        Database.executeBatch(bc, 200);
        Test.stopTest();
    }
}

 

引き続き、よろしくお願い致します。

 

tajimatajima

そのエラーメッセージですと、execute()メソッドが2回以上呼ばれているようですね。

テスト実行時には1回しか呼べない仕様となっています。

 

挙げられたサンプルでは、テストクラスの

'Select c.Id, c.Name From CustomObject__c c Limit 200;

'Select c.Id, c.Name From CustomObject__c c Limit 200';

にし、

 new CustomObject__c(Id = 'id', Name = 'name'); 

 new CustomObject__c(IName = 'name'); 

に修正したら動作しました。

 

挙げられたコードはここに載せるために修正されているようですが

対象のコードでもクエリのlimitとexecuteBatch()のスコープをきちんと指定できていますでしょうか?

 

kyasukyasu

Replyありがとうございます。

 

実際のコードでは、executeBatch()のscopeが抜けていました。

お恥ずかしい限りです。

ありがとうございました。

 

色々いじって分かったのですが、

「テストの実行」ではTestMethodで作ったレコードだけでなく、

実際にあるレコードもBatchクラスの実行に使っているのですね。

tajimatajima

はい、テストクラスが実行されるときには組織上の既存のデータも使われます。

データに対する更新はテストメソッドを抜けるとロールバックされます。

 

なので、本番環境の利用が進むにつれてデータ量が増大し、

作成したときには通ったテストがその後ガバナ制限に抵触して通らなくなるケースがよくあります。

テスト作成時には今後データが増大しても実行できるように、という配慮が必要になります。