[SalesForce] Test Method for @HttpPost RestResource is not returning expected results

I have been looking all over the boards and found some useful posts regarding testing rest services, but even after spending the last 2 hours trying to implement many of those ideas, I still am stuck at the same line.

I have built a very simple @HttpPost request that accepts one parameter, an unformatted phone number. It then uses FIND to get any contacts that match that phone number, casts them to a list of contacts, and then checks if the contact list is empty before continuing on in the code.. here is the basic logic:

    @HttpPost
global static Map<String,String> doPost(String phone){

    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;
    Map<String,String> finalMap = new Map<String,String>();

    List<List<SObject>> searchList = [FIND :phone IN PHONE FIELDS Returning Contact(Id,AccountId,FirstName,LastName,Name,Phone,MobilePhone,HomePhone)];
    List<Contact> contacts = (List<Contact>) searchList[0];

    //finalMap.put('MatchCount',String.valueOf(contacts.size()));
    //Id accId;
    List<Case> caseList = new List<Case>();
    Case c = new Case();
    Set<Id> accountIdSet = new Set<Id>();
    if(!contacts.isEmpty()){
        for(Contact con : contacts){
            if(con.AccountId != null){
                if(!accountIdSet.contains(con.AccountId)){
                    accountIdSet.add(con.AccountId);
                }
            }
        }

When I test this API through Workbench or POSTMan, and pass a JSON body of:
{"phone":"5555555555"} to the endpoint, it works as expected and returns contact results etc.

However, when I test it with my test class (below), it never makes it past the
if(!contacts.isEmpty()) line, which of course means the original searchList returned no results. However, I am passing in the same phone number to the method that the REST Resource would be receiving through the API 5555555555:

    @isTest 
private class PhoneWS_TEST {

@TestSetup
private static void testSetup(){
    Account a = new Account(Name = 'Phone API Test',
                            Billing_Status__c = 'Current',
                            Platform_Application__c = 'Platform',
                            Anniversary_Date__c = System.today(),
                            Zuora__Active__c = 'Yes',
                            Support_Level__c = 'Live',
                            Phone = '5555555555',
                            Email__c = 'fakeem@noreal.com');
    insert a;

    Contact c = new Contact(FirstName = 'Phone',
                            LastName = 'TestUser',
                            Email = 'fakeem@noreal.com',
                            Phone = '5555555555',
                            Title__c = 'CEO',
                            AccountId = a.Id);

    insert c;
}

@isTest
private static void testPhoneLookup() {
    RestRequest req = new RestRequest();
    RestResponse res = new RestResponse();
    req.requestURI = '/services/apexrest/endpoint_name/v1/lookup/phone';
    req.httpMethod = 'POST';
    String phone = '5555555555';
    RestContext.request = req;
    RestContext.response = res;

    Test.startTest();
    Map<String,String> result = PhoneWS_LookupPhone_v1.doPost(phone);
    Test.stopTest();
}
}

Even if I remove the testSetup, and use (SeeAllData=true), it still never makes it past that same line.

So far I've read the following posts:

What am I missing?

Best Answer

Have a read of Adding SOSL Queries to Unit Tests:

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.

Related Topic