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 

Errors with generating an Apex Rest URI callout for doGet. "attempt to de-reference a null object"

Hello,

I am creating a test class for a Rest API class I have with a GET method.

The class itself is pretty simple, It looks for 1 or 2 values for specific objects, queries the database and returns contacts that meet the criteria.

When I run the test class I am getting the error "System.NullPointerException: Attempt to de-reference a null object" pointing at the line with the URI callout and I cannot figure out why.

The class itself is here:
 
@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 {
                String searchText = '%'+searchTerm1+'%';
                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 {
                String searchText = '%'+searchTerm2+'%';
                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{
        
            String searchText1 = '%'+searchTerm1+'%';
            String searchText2 = '%'+searchTerm2+'%';
                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>();
        }
    }
}

It's a bit long but mostly taken up by an IF statement checking how many and which variables were passed in the URI

The test class I have created is below
 
@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(firstName = 'Account1', lastName = 'Contact1', email = 'alex.drew@ttc2.com', RecordTypeId = conRT.get('Travel_Consultant'));
        insert Agency1Contact1;
        
         //There are more records, most have been removed to save space  
    }
    
    @isTest
    //perform first doGet() call
    static void callAPIForTestResults(){
        
        //create records
        createRecords();
        
        test.startTest();
        
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        
        req.requestURI = 'https://XXXX.salesforce.com/services/apexrest/v1/contacts?IATA=12345678&email=alex.drew@ttc2.com';
         
        req.httpMethod = 'GET';
        RestContext.request = req;
        RestContext.response = res;
        
        REST_API_IATA_and_Email_v1.ContactWrapper results = REST_API_IATA_and_Email_v1.doGet();
        
        system.assertEquals('success', results.status);
        system.assertEquals(1, results.acctList.size());
        
        test.stopTest();
    }
}

As I said the error I am getting is "System.NullPointerException: Attempt to de-reference a null object" and pointing at the URI call but I cannot see any problems with it. Can anyone help please

Thanks
Best Answer chosen by Mark Mulholland 3
Dilip_VDilip_V
Hi MArk,

This line is causing error
 
String contactId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);

You havn't assigned rest request URI.

You have to set equest URI in test methods.
 
req.requestURI = '<a target="_blank" href="https://na14.salesforce.com/services/apexrest/v.9/member/me/results/today';" rel="nofollow">https://na14.salesforce.com/services/apexrest/v.9/member/me/results/today';</a>  
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response = res;
String results = MemberRestSvc.doGet();

Let me know if it helps.

If it helps make it as best answer.

Thanks.
 

All Answers

Dilip_VDilip_V
Hi MArk,

This line is causing error
 
String contactId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);

You havn't assigned rest request URI.

You have to set equest URI in test methods.
 
req.requestURI = '<a target="_blank" href="https://na14.salesforce.com/services/apexrest/v.9/member/me/results/today';" rel="nofollow">https://na14.salesforce.com/services/apexrest/v.9/member/me/results/today';</a>  
req.httpMethod = 'GET';
RestContext.request = req;
RestContext.response = res;
String results = MemberRestSvc.doGet();

Let me know if it helps.

If it helps make it as best answer.

Thanks.
 
This was selected as the best answer
Mark Mulholland 3Mark Mulholland 3
Thanks very much for the help!