+ Start a Discussion
adityaMorganadityaMorgan 

Urgent requirement Rest Service Test Class

My class is similar to this class: 

@RestResource(urlMapping='/MyRestContextExample/*')
                           
global with sharing class MyRestContextExample {

    @HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
        return result;
    }
 
}

Test method :

public static testMethod void AttendeeTest(){
        createData();
        String contactId = [Select Id from Contact where Email= : 'testNew@test.com'].Id;
        test.startTest();
        RestRequest req = new RestRequest();
        RestResponse res = new RestResponse();
        req.requestURI = 'https://ap1.salesforce.com/MyRestContextExample/'+contactId;
        req.httpMethod = 'GET';
        system.debug('---requestURI'+req.requestURI);  // here i am getting correct URL 
        List<Account> atndInsert = MyRestContextExample.doGet();
        test.stopTest();
    }

Above method is returning null pointer exception at line 
String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
On debugging I found RestRequest req has value null so req.requestURI is throwing exception. But I am providing request uri in my test class.(req.requestURI= 'https://ap1.salesforce.com/MyRestContextExample/'+contactId;). Then how come it is null. 
Please help.
Best Answer chosen by adityaMorgan
pbattissonpbattisson
You are not setting the Request properly for the callout. In your code you need to add the line

RestContext.request = req;

to set the request for use before calling the request. This will enable your service to use those values.

All Answers

pbattissonpbattisson
You are not setting the Request properly for the callout. In your code you need to add the line

RestContext.request = req;

to set the request for use before calling the request. This will enable your service to use those values.
This was selected as the best answer
adityaMorganadityaMorgan
yes that worked added it in the test class method.. just adding for newbies also metion where to add the code.. i was thinking to add it in my main class.. 
Thnaks, for the help. :)


adityaMorganadityaMorgan
@pbattisson or anyone can explain me give links where they explain purpose of RestContext and RestRequest. I am not able to understand it at all. I have gone through sfdc docs but was not clear about their usage. One usage which i see is to get data from URL.
pbattissonpbattisson
The RestRequest and RestResponse classes represent the request and the response for the API Call that is currently in context they are stored as references in the RestContext class for the call.

So when a call is made to a REST web service the request is stored in the RestContext object as the RestContext.request and is of type RestRequest. It is used for retrieving data from the request including the body parameters and other information. You then set the RestResponse instance in the RestContext.response instance variable with the correct status and other infromation (including information in the response body) to be returned from the apex rest method.
adityaMorganadityaMorgan
Thanks!!
Could you please explain it further "So when a call is made to a REST web service the request is stored in the RestContext object". Here what exactly is request. Is it requestURI, httpMethod etc.?
So in my test class by adding RestContext.request = req, I am storing RestRequest parameters in RestContext. Am I correct? And I think by using RestRequest i can check the response in system.Assert ?
pbattissonpbattisson
The Request is an object containing a set of data (headers, parameters, etc. see https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_restrequest.htm#apex_methods_system_restrequest for full details). By using that method you are stroing the entire request into the request variable on the RestContext object. In the first line of your apex rest method doGet() you then retrieve this same request object using:

RestRequest req = RestContext.request;

That then allows you to access the information about the request. You should then assert on your Account being returned properly. Responses are used with more complex data setups.
adityaMorganadityaMorgan
Ok thanks !! this clears all my doubts. u are better than sfdc docs.