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.

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());
    }
}
  • 1
    You might want to dynamically check how many query rows remain. – Adrian Larson Mar 27 '17 at 17:56
  • @AdrianLarson Done! – Robert Watson Mar 27 '17 at 19:20
  • Loading it statically like that won't necessarily give you an up to date figure, though. – Adrian Larson Mar 27 '17 at 19:25
  • @AdrianLarson Oops - I'm blaming this on Monday. – Robert Watson Mar 27 '17 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.

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

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.