0

I have authored a batch apex and it runs in a specific period of time and checks how many cases are pending in the omnichannel queue. It sends an email when cases count is more than 1.5Lakhs. I am facing a problem with test class, if I try to insert a bulk number of cases, I am getting the error: 'No more than one executeBatch can be called from within a test method'.

global class OmniNotification implements Database.Batchable<sobject>, Database.stateful{
global integer omniCaseCount = 0;
global Database.QueryLocator start(Database.BatchableContext BC){
String query='SELECT id FROM Case where OwnerId in (select id from Group where QueueRoutingConfigId 
!= null)';
return Database.getQueryLocator(query);
}
global void execute(Database.BatchableContext BC, List<Case> scope){
for(case c : scope){
  omniCaseCount++;
}
}
global void finish(Database.BatchableContext BC){
if(omniCaseCount > 150000){
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
  String[] toAddresses = new String[] {'test@test.com'};
  mail.setToAddresses(toAddresses);
  mail.setSubject('Alert-1: Pending Cases in Omni-Channel about to Exceed the Threshold Limit');
  mail.setPlainTextBody('Dear Team, The organization is about to hit the maximum limit of pending 
  cases in the Omni-channel queue. Please take necessary action.');
        mail.setPlainTextBody('Total Cases in the Queue:'+omniCaseCount);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
  }
  }
  }

Could some one please guide an approach on how to cover this logic in test class.

Thanks.

  • Is there a reason you are not using a count() query instead of a batch class? – David Reed Apr 25 at 19:17
  • if I use count operator how can I get the total number of cases in the finish method? By the way, the issue is about how to manage the creation of 1.5lakh cases in test class to cover the finish method. – venky Apr 25 at 19:28
  • @venky You shouldn't be using a batchable for this. The count() query can give you the results in normal apex (e.g. a schedulable class). – sfdcfox Apr 25 at 19:30
  • Actually, stated differently, this is an X-Y Problem. You've made assumptions about how to solve X, and you're stuck on Y, but really you should be asking about how to solve X instead. – sfdcfox Apr 25 at 19:32
  • @sfdcfox thank you very much. I understood and the suggestion worked out for me. i have overridden the variable. – venky Apr 25 at 20:25
1

You can't create 150,000 records in a unit test. This is one of those situations where you'd want to set a variable that is overridden during a unit test:

    global class OmniNotification implements Database.Batchable<sobject>, Database.stateful{
      @testVisible static Integer cutoffLimit = 150000;
      global Database.QueryLocator start(Database.BatchableContext BC){
        return Database.getQueryLocator([SELECT id FROM Case where OwnerId in (select id from Group where QueueRoutingConfigId 
!= null)]);
      } 
      ...
    }

And in your unit test:

@isTest static void test() {
  setupRecords();
  OmniNotification.cutoffLimit = 5;
  Test.startTest();
  Database.executeBatch(new OmniNotification());
  Test.stopTest();
}

As David notes, you should simply use count() to get the total number of records in the queue, rather than counting them one by one. Just to count the number of records that would trigger a notification, you'd need at least 75 executions, meaning this would take minutes to calculate the value, when you could get the results in seconds instead.

Also, if you really wanted to go through this design, you can use simple math instead of counting one by one:

global void execute(Database.BatchableContext BC, List<Case> scope){
  omniCaseCount += scope.size();
}
| improve this answer | |

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.