12

This is my test method for batch process:

static testMethod void TST_testBatch() {

    Test.startTest();
    testBatch b = new testBatch();
    Database.executeBatch(b);
    Test.stopTest();    
}

But I am getting this exception:

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

I have @isTest(SeeAllData=false) at top, but cannot figure out what is causing this error.

UPDATE: I have even kept finish methods as shown below:

global void finish(Database.BatchableContext BC){
    if(!Test.isRunningTest())
     Database.executeBatch(new testBatch()));
}

UPDATE 2:

testBatch execute method:

global void execute(Database.BatchableContext BC, List<sObject> scope){
    Map<Id,SomeOnject> ms = new Map<Id,SomeOnject>();
    for(sObject s: scope)
        ms.put(s.Id,(SomeOnject)s);
    if(ms.size() > 0){
        Map<Id,SomeOnject> toUpdate = new Map<Id,SomeOnject>();
        SomeOnject tmp;
        for(Territory__c t: [SE********************************]){
            tmp = ms.get(t.SFDC__c);
            tmp.SFDCTerritory__c = t.Id;
            tmp.Territory_Nr__c = t.TerritoryNr__c;
            tmp.Territory_Account__c = t.Territory_Account__c; 
            toUpdate.put(tmp.Id,tmp);
        }

        if(toUpdate.size() > 0){
            TerritoryUtils.runUpdateSFDC = false; 
            update toUpdate.values();
        }
    }
}

Start Method:

 global Database.QueryLocator start(Database.BatchableContext BC){
    String query = 'SELECT *************';
    return Database.getQueryLocator(query);
}
2
  • 3
    As far as I see from error message, it is not possible to launch batch job that has more than 1 chunk of data to process in execute method
    – kurunve
    May 17, 2017 at 14:17
  • What query is the batch based on? May 17, 2017 at 14:24

1 Answer 1

19

It looks like you're querying on a Setup object (one not affected by SeeAllData=false), so you'll need to limit your query:

global Database.QueryLocator start(Database.BatchableContext BC){
    String query = 'SELECT *************'+(Test.isRunningTest()?' LIMIT 200':'');
    return Database.getQueryLocator(query);
}
4
  • 1
    How did you come to know this was the problem, I am new to salesforce, Can you please let me know where in the documentation it is written that on 200 is the limit per batch.. It would be helpful for me. May 17, 2017 at 14:44
  • 1
    @NagendraSingh 200 is the default limit. You can add a second parameter to Database.executeBatch to specify a value between 1 and 2,000. This is noted in the Using Batch Apex. Go ahead and give it a read, it'll explain everything for you.
    – sfdcfox
    May 17, 2017 at 14:56
  • Hi @sfdcfox, the error message went away but now there are no values in this line for(Territory__c t: [SE********************************]){ hence it does not proceed to next line in test. Which reduces my test coverage. Can I move my soql in a method and call that method when test is not running else return a list of object required. May 22, 2017 at 5:48
  • 3
    It should be noted that this will apply to test data that exceeds the scope size. So if you have more than 200 records in your test data set, you will hit this. In fact, it is really total records > scope size will cause this because it will split the batch. So you need to make sure your LIMIT value = your scope size.
    – Shanerk
    May 13, 2019 at 16:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .