I'm currently experiencing a problem where a regular old [SELECT ...] query returns results as expected, but a [FIND ...] does not. I have produced a simplified case below:

public class DownloadTest {
    static void canUseFind() {
        String email = '[email protected]';

        // Insert a new lead
        Lead l = new Lead(LastName='Doe', Company='ABC Widgets', Email=email);
        insert l;

        // Can select a lead
        List<Lead> leads = [SELECT Email, LastName FROM Lead];
        System.debug('LEADS1: ' + leads);
        System.assertEquals(1, leads.size());

        List<List<SObject>> res = search.query('FIND \'' + email + '\' IN ALL FIELDS RETURNING Lead');
        System.debug('LEADS2: ' + res);
        System.assertEquals(1, res.get(0).size()); // Failure

The salient part of the debug output:

11:56:22.4 (531026273)|SOQL_EXECUTE_BEGIN|[19]|Aggregations:0|SELECT Email, LastName FROM Lead
11:56:22.4 (553387865)|SOQL_EXECUTE_END|[19]|Rows:1
11:56:22.4 (553670355)|VARIABLE_SCOPE_BEGIN|[19]|leads|List<Lead>|true|false
11:56:22.4 (553849627)|VARIABLE_ASSIGNMENT|[19]|leads|[{"Email":"[email protected]","LastName":"Doe","Id":"00Q8D000003lRxcUAE"}]|0x1060b27e
11:56:22.4 (553864941)|STATEMENT_EXECUTE|[20]
11:56:22.4 (554146833)|USER_DEBUG|[20]|DEBUG|LEADS1: (Lead:{[email protected], LastName=Doe, Id=00Q8D000003lRxcUAE})
11:56:22.4 (554160870)|STATEMENT_EXECUTE|[21]
11:56:22.4 (554302031)|STATEMENT_EXECUTE|[23]
11:56:22.4 (554816404)|SOSL_EXECUTE_BEGIN|[23]|FIND '[email protected]' IN ALL FIELDS RETURNING Lead
11:56:22.4 (571604203)|SOSL_EXECUTE_END|[23]|Rows:0
11:56:22.4 (571707160)|VARIABLE_SCOPE_BEGIN|[23]|res|List<List<SObject>>|true|false
11:56:22.4 (571851657)|VARIABLE_ASSIGNMENT|[23]|res|[[]]|0x2303567e
11:56:22.4 (571861545)|STATEMENT_EXECUTE|[24]
11:56:22.4 (571982014)|USER_DEBUG|[24]|DEBUG|LEADS2: (())

Per recommendations I've found elsewhere (e.x. here), I'm creating records within the test so as not to need isTest(SeeAllData=true).

I'm pretty confident I'm missing something that's going to be obvious to someone else. I've had this working anonymous Apex, so I know the concept works. Just not sure what I'm doing incorrectly here. Thanks folks!

1 Answer 1


You need to use Test.setFixedSearchResults, as search indexes are not updated in real-time, so it is impossible to leverage the search index correctly within a unit test. Further, even with SeeAllData=true, the search index isn't used at all during unit tests. You must always use this method to obtain any search results in SOSL within a unit test. This is an intentional design choice, as laid out in the documentation from above:

To ensure that test methods always behave in a predictable way, any Salesforce Object Search Language (SOSL) query that is added to an Apex test method returns an empty set of search results when the test method executes. If you do not want the query to return an empty list of results, you can use the Test.setFixedSearchResults system method to define a list of record IDs that are returned by the search. All SOSL queries that take place later in the test method return the list of record IDs that were specified by the Test.setFixedSearchResults method. Additionally, the test method can call Test.setFixedSearchResults multiple times to define different result sets for different SOSL queries. If you do not call the Test.setFixedSearchResults method in a test method, or if you call this method without specifying a list of record IDs, any SOSL queries that take place later in the test method return an empty list of results.

  • Thanks @sfdcfox! Nowhere in all my searching over the past couple days did I uncover this. In hindsight, seems a bit more obvious. Jun 16, 2022 at 16:24

You must log in to answer this question.

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