To write a test class for SOSL (Salesforce Object Search Language) queries, you must utilize the Test.setFixedSearchResults()
method. This method is essential because SOSL queries, unlike SOQL, do not automatically query test data created within a test method. Instead, they require you to explicitly define the IDs of the records they should return.
Understanding Test.setFixedSearchResults()
The Test.setFixedSearchResults()
method allows you to pre-define the Id
values that will be returned by any subsequent SOSL query within the current test context. This ensures that your SOSL test methods are deterministic and reliable.
Key Characteristics:
- Input: It accepts a
List<Id>
orId[]
containing the IDs of the records you want the SOSL query to "find." - Behavior: When an SOSL query is executed after
Test.setFixedSearchResults()
has been called, it will return SObjects corresponding to the IDs provided in the specified order. The actual search term used in theFIND
clause of the SOSL query does not matter in this context; only theId
values set by this method determine the results. - Scope: The effect of
Test.setFixedSearchResults()
is limited to the specific test method in which it is called.
How to Write a Test Class for SOSL: Step-by-Step
Follow these steps to effectively test your SOSL queries:
-
Annotate Your Test Class:
Begin by declaring your class with the@isTest
annotation. This marks the class as a test class, ensuring it doesn't count against your organization's Apex code limit and runs in a special test execution context.@isTest private class MySoslTestClass { // Test methods go here }
-
Define a Test Method:
Inside your test class, create one or more test methods. These methods should be annotated with@isTest
or declared asstatic testMethod void
.@isTest private class MySoslTestClass { @isTest static void testMySoslQuery() { // Test logic } }
-
Create Test Data (Recommended):
WhileTest.setFixedSearchResults()
lets you specify any valid Salesforce ID, it's a best practice to create actual test data within your test method. This ensures your tests are isolated, robust, and accurately reflect the types of records your SOSL query is expected to return.// Create an Account Account acc = new Account(Name = 'Test Account for SOSL', Description = 'Test SOSL data'); insert acc; // Create a Contact linked to the Account Contact con = new Contact(FirstName = 'John', LastName = 'Doe', AccountId = acc.Id, Description = 'Another test SOSL data'); insert con;
-
Prepare Fixed Search Results:
Create aList<Id>
orId[]
and populate it with the IDs of the test data you created in the previous step. The order in which you add the IDs does not influence the order of the results returned by SOSL, as SOSL categorizes results by object type.List<Id> fixedResults = new List<Id>(); fixedResults.add(acc.Id); // Add Account ID fixedResults.add(con.Id); // Add Contact ID
-
Call
Test.setFixedSearchResults()
:
InvokeTest.setFixedSearchResults()
and pass your list of IDs. This step is crucial for mocking the SOSL results.Test.setFixedSearchResults(fixedResults);
-
Execute Your SOSL Query:
Now, execute the SOSL query as you normally would. The query will return the records whose IDs you specified usingTest.setFixedSearchResults()
, regardless of theFIND
clause's search term.List<List<SObject>> searchResults = [FIND 'any search term' IN ALL FIELDS RETURNING Account(Id, Name, Description), Contact(Id, FirstName, LastName, AccountId, Description)];
Note: The search term ('any search term' in this example) is effectively ignored when
Test.setFixedSearchResults()
is active. -
Assert the Results:
Finally, write assertions to verify that your SOSL query returned the expected number of records, the correct types of SObjects, and potentially the correct field values.System.assertEquals(2, searchResults.size(), 'Expected two lists of results (Account and Contact).'); // One list for Accounts, one for Contacts // Verify Account results List<Account> accountsFound = (List<Account>)searchResults[0]; System.assertEquals(1, accountsFound.size(), 'Expected one Account record.'); System.assertEquals(acc.Id, accountsFound[0].Id, 'Returned Account ID should match.'); System.assertEquals('Test Account for SOSL', accountsFound[0].Name, 'Returned Account Name should match.'); // Verify Contact results List<Contact> contactsFound = (List<Contact>)searchResults[1]; System.assertEquals(1, contactsFound.size(), 'Expected one Contact record.'); System.assertEquals(con.Id, contactsFound[0].Id, 'Returned Contact ID should match.'); System.assertEquals('John', contactsFound[0].FirstName, 'Returned Contact First Name should match.');
Complete Example
Here is a comprehensive example demonstrating the process:
@isTest
private class SoslSearchTest {
@isTest
static void testSoslResultsWithFixedIds() {
// Step 3: Prepare test data
Account testAccount = new Account(Name = 'Global Solutions Inc.', Description = 'Leading provider of tech solutions');
insert testAccount;
Contact testContact = new Contact(FirstName = 'Alice', LastName = 'Smith', AccountId = testAccount.Id, Email = '[email protected]');
insert testContact;
Opportunity testOpportunity = new Opportunity(Name = 'New Software Deal', StageName = 'Prospecting', CloseDate = Date.today().addDays(30));
insert testOpportunity;
// Step 4: Define the fixed search results with IDs of created records
List<Id> fixedSearchResultIds = new List<Id>();
fixedSearchResultIds.add(testAccount.Id);
fixedSearchResultIds.add(testContact.Id);
fixedSearchResultIds.add(testOpportunity.Id); // Include Opportunity ID
// Step 5: Set the fixed search results for the test context
Test.setFixedSearchResults(fixedSearchResultIds);
// Step 6: Execute the SOSL query
// The search term 'solutions' is irrelevant here due to Test.setFixedSearchResults()
List<List<SObject>> searchResults = [
FIND 'solutions' IN ALL FIELDS
RETURNING
Account(Id, Name, Description),
Contact(Id, FirstName, LastName, Email),
Opportunity(Id, Name, StageName)
];
// Step 7: Assert the results
System.assertEquals(3, searchResults.size(), 'Expected three lists of results (Account, Contact, Opportunity).');
// Verify Account results
List<Account> accounts = (List<Account>)searchResults[0];
System.assertEquals(1, accounts.size(), 'Expected one Account result.');
System.assertEquals(testAccount.Id, accounts[0].Id, 'Retrieved Account ID should match.');
System.assertEquals('Global Solutions Inc.', accounts[0].Name);
// Verify Contact results
List<Contact> contacts = (List<Contact>)searchResults[1];
System.assertEquals(1, contacts.size(), 'Expected one Contact result.');
System.assertEquals(testContact.Id, contacts[0].Id, 'Retrieved Contact ID should match.');
System.assertEquals('Alice', contacts[0].FirstName);
// Verify Opportunity results
List<Opportunity> opportunities = (List<Opportunity>)searchResults[2];
System.assertEquals(1, opportunities.size(), 'Expected one Opportunity result.');
System.assertEquals(testOpportunity.Id, opportunities[0].Id, 'Retrieved Opportunity ID should match.');
System.assertEquals('New Software Deal', opportunities[0].Name);
}
}
This approach ensures that your SOSL test methods are robust, predictable, and maintainable, always returning the specific results you define for your test scenarios.