7

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);
}
  • 1
    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 '17 at 14:17
  • What query is the batch based on? – Jeremy Nottingham May 17 '17 at 14:24
11

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);
}
  • 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. – Nagendra Singh May 17 '17 at 14:44
  • @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 '17 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. – Nagendra Singh May 22 '17 at 5:48
  • 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. – Shane May 13 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.