We have a custom object that once it's saved with a checkbox == true, it has to assign a unique random number to each of its children Cases, but the assigned number can't be either zero nor greater than the total number of child cases (which can get up to +20k records).

I'm writing a batch job to be called once the custom object is saved with the checkbox == true.

  1. The constructor of the batch job class, queries the cases with the criteria to have the random number assigned.
  2. The execute method loops through the cases within the scope, and assigns the random number by calling a custom method getRandomNumber.
  3. This is the custom method gerRandomNumber, where the param upperLimit is the scope.size():

    private Integer getRandomNumber(Integer upperLimit) {
    Integer pulledNumber;
    do {
        pulledNumber = Math.round(Math.random() * upperLimit);
    } while (usedNumbers.contains(pulledNumber));
    return pulledNumber;}
  4. To avoid assigning a repeated number or zero, a static List<Integer> usedNumbers = new List<Integer>{0} is being used.
  5. Finally, to test it I've uploaded a csv file with 10k Cases as a static resource and using it within the test method via the Test.loadData(Case.sObjectType, 'TestCases'); But the test is failing to execute such a long list of Cases. Error is: 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.

Can you advice if this is the correct approach for the objective? And how to overcome the test limitations? Thanks!

3 Answers 3


Sadly the test framework won't let you do that. It's definitely annoying that you can only invoke one batch in the test method. However, you should be able to do this full test manually in a sandbox.

So in this case, the approach would be to use the test framework to sanity check the core logic but do a manual test to ensure the job will run smoothly in your production org.


If you really care about verifying uniqueness across 10,000 records; your testmethod should

  • Construct the batchable
  • call the Batchable's execute() method 10,000/200 = 50 times -- passing in 200 different records each time
  • do whatever verifications you need.

Note that you might run into governor limits (CPU)

  • As you mentioned, I'm bumping with CPU limits. It was worth to try though. Thanks. Commented Mar 18, 2019 at 23:08
  • @sebascanseco - can you use any mocking techniques to mock out unnecessary DML or SOQL (see for example ApexMocks in GitHub)?
    – cropredy
    Commented Mar 18, 2019 at 23:45

We had to think out of the box here. We created a new formula field in the Case object, which would calculate a random number based on a combination of existing fields' values - including date/time created. Then the batch job would just query Cases ordered by this formula field and processes them sequentially assigning an incremental number. This sufficed to give the effect of having randomized numbers.

You must log in to answer this question.

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