Salesforce SOQL-Free Apex Tests with Selector Pattern

Ben Butler
2 min readSep 16, 2021

--

With Apex a Selector Pattern provides multiple benefits including

  • A centralized place to query once, minimizing the number of queries
  • The ability to test the queries in the Selector independent from the classes that utilize the Selector

Selector Patterns can allow for a configurable query. In the case below we configure with Custom Metadata

public class AccountSelector implements IAccountSelector {
public List<Account> selectById(List<Id> accountIds){
list<string> fieldList = new list<string>{ 'Id' };
for (Account_Selector_Field__mdt asf : Account_Selector_Field__mdt.getAll().values())
fieldList.add(asf.fieldname__c);
String accountQuery = 'SELECT {0} FROM Account WHERE Id in (\'{1}\')'
.replace('{0}',String.join(fieldList,','))
.replace('{1}',String.join(accountIds,'\',\''));
return Database.query(accountQuery);
}
}

As indicated create an interface

public interface IAccountSelector {
List<Account> selectById(List<Id> accountIds);
}

The below trigger handler class does not do anything functional but it is an example of how we can inject a Mock of the selector into the constructor. This allows query-free dml-free tests on the class.

public class AccountTriggerHandler {
IAccountSelector accountSelector;
public AccountTriggerHandler(){
accountSelector = new AccountSelector();
}

public AccountTriggerHandler(IAccountSelector anAccountSelector{
accountSelector = anAccountSelector;
}

public List<Account> getAccounts(Id accountId){
return accountSelector.selectById(new List<Id>{ accountId});
}
}

In the test, we can Mock the selection of data by creating a Mock class and generating the data we care about in the Mock.

@isTest
private class AccountTriggerHandlerTest{
static testMethod void testGetAccounts() {
AccountTriggerHandler ath = new AccountTriggerHandler(new AccountSelectorTest());
List<Account> testResults = ath.getAccounts(’0011k0000000000AAA’);
System.assertEquals(testResults[0].Id, '0011k0000000000AAA’);
}
class AccountSelectorTest implements IAccountSelector {
public List<Account> selectById(List<Id> accountIds){
return (List<Account>) JSON.deserialize(
'[{"Id":"0011k0000000000AAA","Name":"testAccount"}]'
 , List<Account>.class
);
}
}
}

The test injects a selector mock now allowing for SOQL-free apex tests. The Selector pattern limits SOQL to tests that test the selector patterns, allowing us to scale with tests that don’t need awkward workaround to queries.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Responses (1)

Write a response