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
Mark Mulholland 3Mark Mulholland 3 

URI in REST API test call not working

Hello,

I have a REST API class with a GET method which finds contacts based on 2 fields that can be passed in the URI. The class itself works when I test it in the Workbench so that doesn't seem to be an issue.

I have created a test class for this and the system.assertequals methods I try keep returning null values, as if the URI is formatted incorrectly. I have checked and rechecked the URI I have used and it should work. I have also checked that the test records I have in the test class are getting created and they are

Can one of you have a look at my test class and see if you can spot what I am missing please. Also I understand that the test class is very basic at the moment, once I fix this issue I will be able to make it more robust


Test Class:
@istest private class REST_API_IATA_and_Email_v1_Tests {

    //Declare variables for records that will be used
    private static Account Agency1;
    
    private static Contact Agency1Contact1;
    
    public static void createRecords(){
        
        //get Account record Types
        map<string, id> mapRT = new map<string, id>();
        for(RecordType RT : [SELECT id, DeveloperName, Name, SobjectType FROM RecordType WHERE SobjectType = 'Account']){
            mapRT.put(RT.DeveloperName, RT.id);
        }

        //get Contact record Types
        map<string, id> ConRT = new map<string, id>();
        for(RecordType RT : [SELECT id, DeveloperName, Name, SobjectType FROM RecordType WHERE SobjectType = 'Contact']){
            ConRT.put(RT.DeveloperName, RT.id);
        }
        
        //insert Accounts to be used in test
        Agency1 = new Account(Name = 'Agency Account 1', IATA_Code__c = '12345678', RecordTypeId = mapRT.get('Agency'));
        insert Agency1;
        
        
        //insert Contacts to be used in test
        Agency1Contact1 = new Contact(AccountId = Agency1.id, firstName = 'Account1', lastName = 'Contact1', email = 'alex.drew@ttc2.com', RecordTypeId = conRT.get('Travel_Consultant'));
        insert Agency1Contact1;   
    }
    
    @isTest
    //perform first doGet() call
    static void callAPIForTestResults(){
        
        //create records
        createRecords();
        
        test.startTest();
        
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();
        
        //make the fake callout to trigger the Rest API
        req.requestURI = 'https://cs86.salesforce.com/services/apexrest/v1/contacts?Email=alex.drew@ttc2.com';
         
        req.httpMethod = 'GET';
        RestContext.request = req;
        RestContext.response = res;
        
        //call the GET method on the Rest API class and envolk the ContactWrapper list
        REST_API_IATA_and_Email_v1.ContactWrapper results = REST_API_IATA_and_Email_v1.doGet();
        
        system.assertEquals(1, results.acctList.size()); //check the GET method was successful with the URI it was given
        
        test.stopTest();
    }
}



REST API Class:
 
@RestResource(urlMapping='/v1/contacts/*')
global with sharing class REST_API_IATA_and_Email_v1 {
    
    @HttpGet
    global static ContactWrapper doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        ContactWrapper response = new ContactWrapper();
        
        String contactId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        
        if(doSearch(contactId)) {
            searchContacts(req, res, response);
        }
        
        return response;
    }
    

    // If the item to the right of the last forward slash is "contacts", the request went to v1/contacts?Name=United
    // Else the request went to v1/contacts/<something>, which is not a search, but a specific entity
    private static boolean doSearch(String contactId) {
        if(contactId == 'contacts') {
            return true;
        }
        return false;
    }
    
    //If the request came to /v1/contacts, then we want to execute a search
    private static void searchContacts(RestRequest req, RestResponse res, ContactWrapper response) {

        //Use the RestRequest's params to fetch the IATA and Email parameters
        String searchTerm1 = req.params.get('IATA');
        String searchTerm2 = req.params.get('Email');
        
        if(searchTerm2 == null || searchTerm2 == ''){
        
            if(searchTerm1 == null || searchTerm1 == '') {
                response.status = 'Error';
                response.message = 'You must provide an IATA Code for your search term.';
                res.StatusCode = 400;
            }
            else {
                List<Contact> searchResults = [SELECT Id, Name, Phone, Email, Account.IATA_Code__c, Account.Name FROM Contact WHERE Account.IATA_Code__c = :searchTerm1];
                
                if(searchResults != null && searchResults.size() > 0) {
                    response.acctList = searchResults;
                    response.status = 'Success';
                    response.message = searchResults.size() + ' Contacts were found that matched your search term.';
                }
                else {
                    response.status = 'Error';
                    response.message = 'No Contacts where found based on that IATA Code, please search again.';
                }
            }
        }
        else if(searchTerm1 == null || searchTerm1 == ''){
        
            if(searchTerm2 == null || searchTerm2 == '') {
                response.status = 'Error';
                response.message = 'You must provide an Email for your search term.';
                res.StatusCode = 400;
            }
            else {
                List<Contact> searchResults = [SELECT Id, Name, Phone, Email, Account.IATA_Code__c, Account.Name FROM Contact WHERE Email = :searchTerm2];
                
                if(searchResults != null && searchResults.size() > 0) {
                    response.acctList = searchResults;
                    response.status = 'Success';
                    response.message = searchResults.size() + ' Contacts were found that matched your search term.';
                }
                else {
                    response.status = 'Error';
                    response.message = 'No Contacts where found based on that Email, please search again.';
                }
            }
        }    
        else{
        
                List<Contact> searchResults = [SELECT Id, Name, Phone, Email, Account.IATA_Code__c, Account.Name FROM Contact WHERE Account.IATA_Code__c = :searchTerm1 AND Email = :searchTerm2];
                
                if(searchResults != null && searchResults.size() > 0) {
                    response.acctList = searchResults;
                    response.status = 'Success';
                    response.message = searchResults.size() + ' Contacts were found that matched your search terms.';
                }
                else {
                    response.status = 'Error';
                    response.message = 'No Contacts where found based on that IATA Code and email, please search again.';
                }
            }
            
    }

    
    global class ContactWrapper {
        public List<Contact> acctList;
        public String status;
        public String message;
        
        public ContactWrapper(){
            acctList = new List<Contact>();
        }
    }
}



Thanks very much
Best Answer chosen by Mark Mulholland 3
karthikeyan perumalkarthikeyan perumal
Hello

Try Below Code, 
@istest private class REST_API_IATA_and_Email_v1_Tests {

    //Declare variables for records that will be used
    private static Account Agency1;
    
    private static Contact Agency1Contact1;
    
    public static void createRecords(){
        
        //get Account record Types
        map<string, id> mapRT = new map<string, id>();
        for(RecordType RT : [SELECT id, DeveloperName, Name, SobjectType FROM RecordType WHERE SobjectType = 'Account']){
            mapRT.put(RT.DeveloperName, RT.id);
        }

        //get Contact record Types
        map<string, id> ConRT = new map<string, id>();
        for(RecordType RT : [SELECT id, DeveloperName, Name, SobjectType FROM RecordType WHERE SobjectType = 'Contact']){
            ConRT.put(RT.DeveloperName, RT.id);
        }
        
        //insert Accounts to be used in test
        Agency1 = new Account(Name = 'Agency Account 1', IATA_Code__c = '12345678', RecordTypeId = mapRT.get('Agency'));
        insert Agency1;
        
        
        //insert Contacts to be used in test
        Agency1Contact1 = new Contact(AccountId = Agency1.id, firstName = 'Account1', lastName = 'Contact1', email = 'alex.drew@ttc2.com', RecordTypeId = conRT.get('Travel_Consultant'));
        insert Agency1Contact1;   
    }
    
    @isTest
    //perform first doGet() call
    static void callAPIForTestResults(){
        
        //create records
        createRecords();
        
        test.startTest();
        
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();
        
        //make the fake callout to trigger the Rest API
        req.requestURI = 'https://cs86.salesforce.com/services/apexrest/v1/contacts?Email=alex.drew@ttc2.com';
         
        req.httpMethod = 'GET';
        RestContext.request = req;
        RestContext.response = res;
        
        //call the GET method on the Rest API class and envolk the ContactWrapper list
        REST_API_IATA_and_Email_v1.ContactWrapper results = REST_API_IATA_and_Email_v1.doGet();      
        		
		System.debug('List Size'+results.acctList.size());
        
        test.stopTest();
    }
}

Hope this will help you.. 
Mark Best Answer  if its work for you. 

Thanks
karthik
 

All Answers

karthikeyan perumalkarthikeyan perumal
Hello

you are getting any error something like this
System.Exception: Assertion Failed: Expected

Thanks
karthik
 
Mark Mulholland 3Mark Mulholland 3
Hello Karthik,

Sorry I should have been clear about the error. That is correct

When I run the test I get the error

"System.AssertException: Assertion Failed: Expected: 1, Actual: 0"

Thanks
Mark
karthikeyan perumalkarthikeyan perumal
Hello

Try Below Code, 
@istest private class REST_API_IATA_and_Email_v1_Tests {

    //Declare variables for records that will be used
    private static Account Agency1;
    
    private static Contact Agency1Contact1;
    
    public static void createRecords(){
        
        //get Account record Types
        map<string, id> mapRT = new map<string, id>();
        for(RecordType RT : [SELECT id, DeveloperName, Name, SobjectType FROM RecordType WHERE SobjectType = 'Account']){
            mapRT.put(RT.DeveloperName, RT.id);
        }

        //get Contact record Types
        map<string, id> ConRT = new map<string, id>();
        for(RecordType RT : [SELECT id, DeveloperName, Name, SobjectType FROM RecordType WHERE SobjectType = 'Contact']){
            ConRT.put(RT.DeveloperName, RT.id);
        }
        
        //insert Accounts to be used in test
        Agency1 = new Account(Name = 'Agency Account 1', IATA_Code__c = '12345678', RecordTypeId = mapRT.get('Agency'));
        insert Agency1;
        
        
        //insert Contacts to be used in test
        Agency1Contact1 = new Contact(AccountId = Agency1.id, firstName = 'Account1', lastName = 'Contact1', email = 'alex.drew@ttc2.com', RecordTypeId = conRT.get('Travel_Consultant'));
        insert Agency1Contact1;   
    }
    
    @isTest
    //perform first doGet() call
    static void callAPIForTestResults(){
        
        //create records
        createRecords();
        
        test.startTest();
        
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();
        
        //make the fake callout to trigger the Rest API
        req.requestURI = 'https://cs86.salesforce.com/services/apexrest/v1/contacts?Email=alex.drew@ttc2.com';
         
        req.httpMethod = 'GET';
        RestContext.request = req;
        RestContext.response = res;
        
        //call the GET method on the Rest API class and envolk the ContactWrapper list
        REST_API_IATA_and_Email_v1.ContactWrapper results = REST_API_IATA_and_Email_v1.doGet();      
        		
		System.debug('List Size'+results.acctList.size());
        
        test.stopTest();
    }
}

Hope this will help you.. 
Mark Best Answer  if its work for you. 

Thanks
karthik
 
This was selected as the best answer
Mark Mulholland 3Mark Mulholland 3
Hello Karthik,

That worked thanks, however the result is still that no contact gets returned, right?

My understanding is that because the URI contains an email address that exists on a contact, that the API should add that contact to the acctList list and that the Assert I had before should say the size of the list is 1

Do you know if there is something I am missing from my test that should make this happen?

Thanks
Mark
karthikeyan perumalkarthikeyan perumal
Hello, 

That is case, your list dont not contain any contact. 

First thing 

you are inserting dummy test data 
 insert Agency1Contact1;  
and you trying to fetch the data from contact object  name of test email name.
https://cs86.salesforce.com/services/apexrest/v1/contacts?Email=alex.drew@ttc2.com';
check the its return contact or not.  
try some other email address which is there in contact list. 

chekc one more round of your rest call and  ContactWrapper class.

try some debug code here
 
{
        
                List<Contact> searchResults = [SELECT Id, Name, Phone, Email, Account.IATA_Code__c, Account.Name FROM Contact WHERE Account.IATA_Code__c = :searchTerm1 AND Email = :searchTerm2];
                
                if(searchResults != null && searchResults.size() > 0) {
                    response.acctList = searchResults;
                    response.status = 'Success';
                    response.message = searchResults.size() + ' Contacts were found that matched your search terms.';
                }
                else {
                    response.status = 'Error';
                    response.message = 'No Contacts where found based on that IATA Code and email, please search again.';
                }
            }

Thanks
karthik
 
Mark Mulholland 3Mark Mulholland 3
Thanks for the help Karthik