function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
lxchlxch 

Plot accounts or leads on Google Map with SOSL [debug]

This whole works fine in sandbox but I couldn't figure out where to test to clear the test coverage. Thanks for your help!

ApexClass
public with sharing class AccountSearchController {
    @AuraEnabled
    public static List<Account> searchAccounts( String searchTerm, String searchOption, Integer searchLimit, Integer searchRadius ) {            
        List<Account> accounts = new List<Account>(); 
        if ( String.isNotBlank( searchTerm ) ) {
        	List<List<SObject>> results = [FIND :searchTerm IN ALL FIELDS
                    RETURNING Account(
                      Id, BillingLatitude, BillingLongitude
                      WHERE BillingLatitude != Null AND BillingLongitude !=null
                      LIMIT 1)
            ];
            Account [] tempAccts = (Account[])results[0];
            Account centerAcct = tempAccts.get(0);
            
            List<List<SObject>> searchResults = [FIND :searchTerm IN ALL FIELDS
                RETURNING Account(
                    Id,Name,BillingAddress,Recent_Closed_Won_Date__c,Last_Sales_Activity__c,Last_Sales_Activity_By__c,Related_Opportunities_y__c,Owner_Alias__c,Client_Type_new__c,Industry,BillingState,BillingCity,BillingStreet,BillingPostalCode,BillingLatitude,BillingLongitude
                	WHERE DISTANCE (BillingAddress, Geolocation(:centerAcct.BillingLatitude, :centerAcct.BillingLongitude),'km')<:searchRadius
                    ORDER BY Related_Opportunities_y__c DESC
                    LIMIT :searchLimit
                )
            ];
            accounts = searchResults[0];
       
        }  else {
                List<List<SObject>> searchResults = [
                FIND '東京都' IN ALL FIELDS
                RETURNING Account(
                    Id,Name,BillingAddress,Recent_Closed_Won_Date__c,Last_Sales_Activity__c,Last_Sales_Activity_By__c,Related_Opportunities_y__c,Owner_Alias__c,Client_Type_new__c,Industry,BillingState,BillingCity,BillingStreet,BillingPostalCode,BillingLatitude,BillingLongitude
                    ORDER BY Related_Opportunities_y__c DESC
                    LIMIT :searchLimit
                )
            ];
            accounts = searchResults[0];
        }        
    	return accounts;
    }
    @AuraEnabled   
    public static List<Lead> searchLeads(  String searchTerm, String searchOption, Integer searchLimit, Integer searchRadius ) {            
        List<Lead> leads = new List<Lead>();   
        if ( String.isNotBlank( searchTerm ) ) {
	       	List<List<SObject>> results = [FIND :searchTerm IN ALL FIELDS
                           RETURNING Lead(
                           Id, Latitude, Longitude
                           WHERE Latitude != Null AND Longitude !=null
                           LIMIT 1)
                           ];
            Lead [] tempLeads = (Lead[])results[0];
            Lead centerLead = tempLeads.get(0);
            
            List<List<SObject>> searchResults = [
                FIND :searchTerm IN ALL FIELDS
                RETURNING Lead(
                    Id,LastName,Address,Company,State,City,Street,PostalCode,Latitude,Longitude,Owner__c, Client_Type_new__c
                    WHERE Latitude !=null AND Longitude !=null AND DISTANCE (Address, Geolocation(:centerLead.Latitude, :centerLead.Longitude),'km')<:searchRadius
                    ORDER BY Company DESC
                    LIMIT :searchLimit
                )
            ];
            leads = searchResults[0];
        }
    	return leads;
    }
}

Test Class
@isTest
public with sharing class AccountSearchControllerTest {

    @isTest
    public static void testAccountSearchController() {
        Account acct = new Account(Name ='Test');
        acct.BillingPostalCode = '105-0011';
        acct.BillingCountry = 'JP';
        acct.BillingState = 'Tokyo';
        acct.BillingCity = 'Minato';
        acct.BillingStreet = 'Shibakoen 3-1-1';
        acct.BillingLatitude = 35.661;
        acct.BillingLongitude = 139.748;
        insert acct;
                
        Lead lead = new Lead (LastName ='Test');
        lead.PostalCode = '105-0011';
        lead.Country = 'JP';
        lead.State = 'Tokyo';
        lead.City = 'Minato';
        lead.Street = 'Shibakoen 3-1-1';
        lead.Latitude = 35.661;
        lead.Longitude = 139.748; 
        insert lead;
        
        Test.startTest();
            List<Account> searchAccounts = AccountSearchController.searchAccounts(acct.BillingState,'option1',25,6);
            System.assertEquals(true,searchAccounts.isEmpty());
      
            List<Lead> searchLeads = AccountSearchController.searchLeads(lead.State,'option2',25,6);
            System.assertEquals(true,searchLeads.isEmpty());
        Test.stopTest();

    }
}

I attached the debug result with highlighting the lines are not test.
Thank you!
Best Answer chosen by lxch
vishal-negandhivishal-negandhi

Hi there, 

So as per salesforce documentation here - https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_SOSL.htm

SOSL's don't return any results in test classes and you need to specify search result ID in your test class. 

Test.startTest();
         	Id [] fixedSearchResults= new Id[1];
       		fixedSearchResults[0] = acct.Id;
       		Test.setFixedSearchResults(fixedSearchResults);
                List<Account> searchAccounts = 
                DemoComponentController.searchAccounts(acct.BillingState,'option1',25,6);
                System.assertEquals(false,searchAccounts.isEmpty());
Test.stopTest();


You will need to to do this for both your SOSL queries. 

Hope this helps.

All Answers

lxchlxch

Here's test log :/

User-added image
vishal-negandhivishal-negandhi
Your code is running into an exception on this line 
Account centerAcct = tempAccts.get(0);

You must add a check if tempAccts is empty and only then execute the above statement. 
 
lxchlxch
Hi @vishal-negandhi, thank you very much for your advice. I will test it today and report back here!
lxchlxch
hmmm... still don't know how to check if tempAccts is empty in Test Class. I tried to add tempAccts in the Test code, but I can't figure out how to reach it. Inserting below is not enough, the error message in Developeer Consule is "Variable does not exist: tempAccts"
System.assertEquals(false,tempAccts.isEmpty());   
​​​​​​​System.assertEquals('東京都',centerAcct.BillingState);
Class
https://gist.github.com/liuxiachanghong/f042d78d2e5153ee181151ff11a3718a

Test Class
https://gist.github.com/liuxiachanghong/146599eae9420d13f1cdd0a62685d900

Demo (the components work perfect in the sandbox, but can't deploy to the produciton because of test code ....)
https://drive.google.com/file/d/1YsdYhL4yGSulCbzyb0oiBQrXSo9J1zNF/view?usp=sharing
lxchlxch
I added in the Class to check if tempAccts !=null, but it returns the same test coverage...
... / row 14
Account[] tempAccts = (Account[])results[0];
            if (tempAccts != null) {
                Account centerAcct = tempAccts.get(0);              
                List<List<SObject>> searchResults = [FIND :searchTerm IN ALL FIELDS
                    RETURNING Account( Id,Name,BillingAddress,Recent_Closed_Won_Date__c,Last_Sales_Activity__c,Last_Sales_Activity_By__c,Related_Opportunities_y__c,Owner_Alias__c,Client_Type_new__c,Industry,BillingState,BillingCity,BillingStreet,BillingPostalCode,BillingLatitude,BillingLongitude
                        WHERE DISTANCE (BillingAddress, Geolocation(:centerAcct.BillingLatitude, :centerAcct.BillingLongitude),'km')<:searchRadius
                        ORDER BY Related_Opportunities_y__c DESC
                        LIMIT :searchLimit
                    )
                ];
                accounts = searchResults[0];
            }
....

 
vishal-negandhivishal-negandhi

Hi there, 

So as per salesforce documentation here - https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_SOSL.htm

SOSL's don't return any results in test classes and you need to specify search result ID in your test class. 

Test.startTest();
         	Id [] fixedSearchResults= new Id[1];
       		fixedSearchResults[0] = acct.Id;
       		Test.setFixedSearchResults(fixedSearchResults);
                List<Account> searchAccounts = 
                DemoComponentController.searchAccounts(acct.BillingState,'option1',25,6);
                System.assertEquals(false,searchAccounts.isEmpty());
Test.stopTest();


You will need to to do this for both your SOSL queries. 

Hope this helps.

This was selected as the best answer
lxchlxch
@vishal-negandhi thank you again for the advice and URL. It is definitely a blind spot that SOSL doesn't return any results in test classes... I'll test as advised later and report back here!
lxchlxch

@vishal-negandhi really really thank you! I finally made the test coverage 100% because of your advise. Yes, it's all caused from the SOSL not returning any results in the test class, and I cleaned a little more non-necessary SOSL in the Class. The link you gave me save me from endless errors in vain. Thank you!

Class (final version)
https://gist.github.com/liuxiachanghong/f042d78d2e5153ee181151ff11a3718a

Test Class (final version)
https://gist.github.com/liuxiachanghong/146599eae9420d13f1cdd0a62685d900

vishal-negandhivishal-negandhi
I am super glad that your issue is fixed. You're welcome!