I'm new to salesforce, but have been given a task that I am puzzled on. I am given a test class with an @testSetup method which inserts relevant data for the test methods. In my test method, SOQL calls works, but SOSL does not, whereas if I run SOSL calls in the @testSetup method, it works fine. I am thinking this is a problem of scope, but I don't know how to pass the relevant data to my test methods (I tried making fixedSearchResults global but that didn't work). Example code below:

@isTest
private class Test_Class {

    @testSetup static void initializeData() {
                Account acct = new Account(Name = 'Acme');
                insert acct;

                list<id> fixedSearchResults = new list<id>();
                fixedSearchResults.add(acct.Id);
                Test.setFixedSearchResults(fixedSearchResults);

                //SOSL -- works as expected
                List<List<sObject>> testAccountList2 = [FIND 'test' 
                                        IN ALL FIELDS RETURNING 
                                        Account(name, id  WHERE name = 'Acme')];   
                System.debug(testAccountList2[0][0].Id);
                System.debug(testAccountList2[0][0].get('Name'));

                //SOQL -- Works as expected
                Account acct2 = [SELECT Name FROM Account WHERE Name='Acme' LIMIT 1];
                System.debug(acct2);
        }

        static testMethod void testingMethod() {
                test.startTest();
                myClass q = new myClass(); //test my class (not relevant here though)
                test.stopTest();

                //SOQL -- THIS WORKS
                Account acct2 = [SELECT Name FROM Account WHERE Name='Acme' LIMIT 1];
                System.debug(acct2);

                /*
                THIS WOULD MAKE THE SOSL CALL BELOW WORK, BUT DEFEATS THE PURPOSE OF THE initializeData() METHOD

                Account acct = new Account(Name = 'Acme');
                insert acct;

                list<id> fixedSearchResults = new list<id>();
                fixedSearchResults.add(acct.Id);
                Test.setFixedSearchResults(fixedSearchResults);
                */

                //SOSL -- Out of bounds... Nothing is grabbed.
                List<List<sObject>> testAccountList2 = [FIND 'test' 
                                        IN ALL FIELDS RETURNING 
                                        Account(name, id  WHERE name = 'Acme')];   
                System.debug(testAccountList2[0][0].Id);
                System.debug(testAccountList2[0][0].get('Name'));
        }   
}

So how can I get the testMethod SOSL calls to work without having to repeat adding fixedSearchResults?

  • You might have probably read this but documentation says that we need to set the test SOSL results in every test method. I understand that if we have to set in every test method what is the use of testsetup method.. May be bug with the platform? – javanoob Sep 16 '15 at 20:22
  • I think this is an issue with scope (of setFixedSearchResults) but also I do not understand the purpose of the testing here. @testsetup is to setup test data. Put the string "test" in the setup data to avoid the issue. The initializedata() method's purpose is to setup your test data. If you want to attempt to find a record that doesn't exist then that is possible but you will need more error trapping. – Ant Smith Sep 16 '15 at 21:27
  • @AntSmith Can you explain on what do you mean by "put the string "test" in the setup data"? – javanoob Sep 16 '15 at 21:46
up vote 2 down vote accepted

@TestSetup only creates records that will be used for the entire set of unit tests. It cannot populate static or instance variables, as the memory graph will be wiped clean for each test run. That means you'll still need to call setFixedSearchResults at the beginning of each unit test. I recommend a static function that you can call to repopulate the appropriate values; you'll still use queries to get your data at the start of each unit test, but @TestSetup allows you to save time by inserting records just once instead of invoking all of their trigger logic each run. This can easily save you several seconds or more per unit test (in one instance, I was saving 5-6 seconds per unit test over 170 unit tests, which reduced deployment time by over ten minutes). In fact, this very type of problem I had prompted me to post this idea on the IdeaExchange. You may want to go vote for it!

  • So the @TestSetup method is only for inserting records, and I should have another static function to create/return the fixedSearchResults variable? – user24755 Sep 17 '15 at 15:56
  • That's how it goes. At least you get to save in trigger execution time. – sfdcfox Sep 17 '15 at 15:57

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.