I am developing a Apex REST class for an external system. I have done with the development and everything is working good.
Now I am creating test classes for this Rest class.
Problem I want to set params in RestContext.request.params
but it is not setting parameters.
Below is my Rest class
@RestResource(urlMapping='/ownerPortal')
global class Rest_Services_Owner_Portal {
Private static String ACTION_PARAM = 'action';
Private static String TEST_SERVICE = 'testService';
Private static String GET_BANK_DETAILD = 'getBankDetails';
Private static String EDIT_BANK_DETAILD = 'editBankDetails';
Private static String CREATE_BANK_DETAILD = 'createBankDetails';
public static Object result;
public static String jsonString{get{
return JSON.serialize(result);
}set;}
@HttpPost
global static void handleRequest() {
RestResponse response = RestContext.response;
try{
response.addHeader('Content-Type','application/json');
RestRequest req = RestContext.request;
Map<String,String> headersMap = req.headers;
if(!req.params.containsKey('action')){
throw New CustomException('action parameter is required!');
}
if(String.isBlank(headersMap.get('CRS_Authorization'))){
throw New CustomException('CRS authorization header missing!');
}
String action = req.params.get('action');
if(TEST_SERVICE.equalsIgnoreCase(action)){
result = Rest_Services_Owner_Portal_Handler.testService(req.requestBody.toString());
}else{
throw New CustomException('Invalid action!');
}
}catch(CustomException cx){
response.statusCode = 403;
result = New ResponseClass('error',null,cx.getMessage(),cx.getMessage());
}catch(Exception ex){
result = New ResponseClass('error',null,ex.getMessage(),ex.getMessage());
}
response.responseBody = Blob.valueOf(jsonString);
}
}
And following is my ServiceHandler class
public class Rest_Services_Owner_Portal_Handler {
public Rest_Services_Owner_Portal_Handler() {
}
public static Object testService(String data){
System.debug(data);
return New ResponseClass('success',JSON.deserializeUntyped(data),'Services are working!','Services are working!');
}
}
And following is my Response Class
public with sharing class ResponseClass {
public String status{get;set;}
public Object result{get;set;}
public String message{get;set;}
public String debugMessage{get;set;}
public ResponseClass(){
}
public ResponseClass(String status,Object result,String message,String debugMessage) {
this.status = status;
this.result = result;
this.message = message;
this.debugMessage = debugMessage;
}
}
Below is my Test class
@isTest
private class Test_Rest_Services_Owner_Portal {
@testSetup static void setupTestData(){
}
static testMethod void testService() {
RestRequest req = new RestRequest();
req.requestURI = Constants.OWNER_PORTAL_ENDPOINTS.get('testService');
req.httpMethod = 'POST';
req.addHeader('CRS_Authorization','00DO000000537j1!ARsAQHvz9MMOxZ24dez0hCYWl0_WpITR1kIoOv3wo67zV6a48Y0RYN9FEzPQf.73.7TZGrVEnq_9X5zLGryMAVVNnQO4jehD');
Map<Object,Object> requestMap = New Map<Object,Object>{
'test' => 'test'
};
req.addParameter('action','testService');
req.requestBody = Blob.valueOf(JSON.serialize(requestMap));
RestContext.request = req;
System.debug(req);
Rest_Services_Owner_Portal.handleRequest();
RestResponse response = RestContext.response;
System.debug(response.responseBody.toString());
}
}
Anyone have any Idea, how to test Rest class written in above pattern.
Thanks
Best Answer
In unit tests neither
RestContext.request
orRestContext.response
are automatically initialised whereas in the normal execution environment they are. So if your@RestResource
class references these values you need to set both of them up in your test.So add to your test before the call to the
@HttpPost
method:so that this line in your
@HttpPost
method:does not cause an NPE that breaks your test because
response
is null.