4

I have some code that is failing in my UAT environment where there are more than 50,000 accounts.

The code, does an unconstrained SELECT ID FROM ACCOUNT and hits the SOQL limit.

The fix is obvious and trivial, however, I would like to develop a unit test for this scenario, but despite trying @future as well as trying to do it via a Database.Batchable (which fails because execute may only be called once from a test method) I'm not able to create more than 10,000 rows (the DML limit).

We have other options for testing this, as an integration test run under another framework, but it might be cleaner for us to do this as a unit test.

2 Answers 2

6

Another option besides @SeeAllData=true would be to force a different limit if running in a unit test context.

The downside to this approach is that you're simply testing that the SOQL Limit clause is working correctly, not that the code isn't throwing exceptions. The upside is that your unit test is probably going to run much more quickly than if you were creating thousands of records.

For example:

public with sharing class AccountSelector {
    @testVisible private Integer getQueryLimit() {
        return Test.isRunningTest() ? 
            50 : Limits.getLimitQueryRows()-Limits.getQueryRows(); 
    }

    public List<Account> query() {
        return [SELECT Id FROM Account LIMIT :getQueryLimit()];
    }
}

Test Class:

@isTest private class AccountSelectorTest {
    @isTest static void QueryTest() {
        AccountSelector actSelector = new AccountSelector();

        // Insert 10 more accounts than the query limit
        Integer queryLimit = actSelector.getQueryLimit();
        List<Account> accounts = new List<Account>();
        for (Integer i = 0; i < queryLimit+10; i++) {
            accounts.add(new Account(Name = 'Test ' + i));
        }
        insert accounts;

        // Assert that the method only selects queryLimit accounts
        Test.startTest();
        List<Account> accountsReturned = actSelector.query();
        Test.stopTest();
        System.assertEquals(queryLimit, accountsReturned.size());
    }
}
4
  • 1
    You might want to dynamically check how many query rows remain.
    – Adrian Larson
    Commented Mar 27, 2017 at 17:56
  • @AdrianLarson Done! Commented Mar 27, 2017 at 19:20
  • Loading it statically like that won't necessarily give you an up to date figure, though.
    – Adrian Larson
    Commented Mar 27, 2017 at 19:25
  • @AdrianLarson Oops - I'm blaming this on Monday. Commented Mar 27, 2017 at 20:04
3

If you want to write unit tests against more records than can be created in a single context, your only real option is to use SeeAllData=true. It doesn't really help you in sandbox environments that don't already have that volume of data, but can be used to protect your production environment.

2
  • 1
    I've not tried but would using a static resource and test.Load data work? I guess it wouldn't...
    – Girbot
    Commented Mar 27, 2017 at 19:06
  • 1
    @Girbot I believe each DML row still counts against you so it'd be the same governor.
    – Adrian Larson
    Commented Mar 27, 2017 at 19:06

You must log in to answer this question.

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