Stat Tracker

Thursday, January 12, 2012

Executing SOSL in Unit Tests

SOSL is a very powerful query method available in the Force.com platform. It allows you to query across all objects for matching text and return results in a List<List<Sobject>> result set. Very cool and very powerful.

As with any Apex code you'll need to write some unit tests to ensure code coverage and that the queries behave as designed before deploying to production. The funny thing is if you just dive right into writing some SOSL queries in Apex and try to test it, you may notice that you get 0 results back for your data. What gives? You know the code is correct. You know the code is working in your sandbox via testing it in a Visualforce page. What the heck?

You're not having a heart attack There is no issue, you just need to know how to setup your unit test properly! Because Salesforce is a multi-tenant architecture, and queries are shared across the system, they don't allow you to run the full SOSL query in your unit test since SOSL can go across all objects in the org. Fear not though, you can still test your code and the query!

You need to use the Test.setFixedSearchResults() method inside your unit test to set a subset of available data to the SOSL query. This method will open up these records so that they can be searched on by the SOSL in your unit test.

For example, lets say I have an Apex class which has a method called "search()" which executes the SOSL like so:


List<List<SObject>> searchList = [FIND :param IN ALL FIELDS RETURNING Account(Id,Name), Contact(Id,Name), Opportunity(Id,Name)];

If I setup my Unit Test as follows, it will query on the data properly and return 3 results back (1 result for each object type):

        Account a = UnitTestFactory.buildTestAccount();
        insert a;
       
        Contact c = UnitTestFactory.buildTestContact();
        insert c;
       
        Opportunity o = UnitTestFactory.buildTestOpportunity();
        insert o;
       
        Id [] fixedSearchResults= new Id[3];
        fixedSearchResults[0] = a.Id;
        fixedSearchResults[1] = c.Id;
        fixedSearchResults[2] = o.Id;
        //Required so SOSL will fire in Unit Tests Properly
        Test.setFixedSearchResults(fixedSearchResults);
       
        CustomSearchController rs = new CustomSearchController();
        rs.searchParam = 'Unit';
       
        test.startTest();
        rs.search();
        test.stopTest();
       
        system.assertEquals(3,rs.results.size());



This Unit Test code will execute and give me the 3 results I am expecting. That's it. You can now test your SOSL queries properly and ensure that they work! Easy enough!

For more information you can checkout the documenation on Force.com: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_SOSL.htm