[SalesForce] params in the rest request is coming as null

I am trying to write a test class for a rest web service @httppost method.
Here is my code

 public static testMethod void testPostRestService () {

    JsonToLeadDataClass outerJsonObj = new JsonToLeadDataClass();
    outerJsonObj.leadName = 'hello lead';
    outerJsonObj.city = 'Bang';
    outerJsonObj.address = 'dsadaa';
    outerJsonObj.company = 'saasasd';
    outerJsonObj.country = 'India';
    outerJsonObj.email = 'abc@dgmail.com';
    outerJsonObj.phone = '09139saa828';
    outerJsonObj.state = 'Karnatka';

    List<JsonToLeadDataClass.booking_data> innerJsonObj = new List<JsonToLeadDataClass.booking_data>();

    JsonToLeadDataClass.booking_data obj = new JsonToLeadDataClass.booking_data();
    obj.booking_date = 'Mon Jan 15,2018';
    obj.booking_id = 123;
    obj.end_time = '12:00 PM';
    obj.start_time = '12:00 AM';
    obj.centre_name = 'abc';
    obj.guest_name = 'abcxyz';
    obj.seats = 432;
    obj.room_name = 'bdkaskja';
    innerJsonObj.add(obj);
    outerJsonObj.booking_data = innerJsonObj;

    String jsonReq = JSON.serialize(outerJsonObj);
    System.debug('json string is: ' + jsonReq);

    Map<String, Object> requestMap = (Map<String, Object>) JSON.deserializeUntyped(jsonReq);
    System.debug('request Map is: ' + requestMap);

    RestRequest req = new RestRequest();
    RestResponse res = new RestResponse();
    req.requestURI = 'https://cs57.salesforce.com/services/apexrest/Lead/';
    req.httpMethod = 'POST';
    System.debug('requestMap serialized : ' + JSON.serialize(requestMap));

    /*System.debug('request Map key set is: ' + requestMap.keySet());
    for(String ob : requestMap.keySet()) {
        if(requestMap.containsKey(ob))
            RestContext.request.params.put(ob, String.valueOf(requestMap.get(ob)));
    }*/

    req.requestBody = Blob.valueOf(JSON.serialize(requestMap));
    System.debug('req.requestBody is: ' + req.requestBody);
    RestContext.request = req;
    RestContext.response = res;
    RestContext.request.addHeader('Content-Type', 'x-www-form-urlencoded');
    RestContext.request.addParameter('','');

    System.debug('rest context request is: ' + RestContext.request);

    Test.startTest();
    NucleusAPI.createLeadAPI();
    Test.stopTest();
}

Logic in my NucleusAPI goes something like this:
I am exposing an URI using @httppost method which will be receiving a json file and I will deserialize that json file and will create a lead record into salesforce.

This is how I am deserializing when the url is hit and receives a json file:

params = System.RestContext.request.params;
                body = String.valueOf(params);
                System.debug('body without testing: ' + body);
                body = body.substring(1, body.length()-2);
 JsonToLeadDataClass jsonFile = (JsonToLeadDataClass)JSON.deserialize(body, JsonToLeadDataClass.class); 
            System.debug('jsonFile is: ' + jsonFile);
            List<JsonToLeadDataClass.booking_data> listBD = (List<JsonToLeadDataClass.booking_data>)jsonFile.booking_data;
            System.debug('listBD is: ' + listBD);

and my json file look something like this:

{
  "state": "Karnatka",
  "phone": "09139828",
  "leadName": "hello lead",
  "email": "abc@asa.com",
  "country": "India",
  "company": "sasad",
  "city": "Bang",
  "booking_data": [
    {
      "start_time": "12:00 AM",
      "seats": 432,
      "room_name": "bdkaskja",
      "guestName": "abcxyz",
      "end_time": "12:00 PM",
      "centre_name": "axasa",
      "booking_id": 123,
      "booking_date": "Mon Jan 15,2018"
    }
  ],
  "address_1": "dsadaa"
}

I need help with with this. the param in the REST Request is being set as null.. how can I set the jsonbody into the params. I tried using traversing the json map and tried puttnig the values into param map but somehow that gives me a null exception error. also I am not able to decode the request body in the NucleusAPI class.

Can somebody please help me with this.

Best Answer

I would normally expect the JSON payload to be sent in the Request body, rather than in the params?

So something like this in the NucleusAPI:

@HttpPost
global static void createLeadApi() {
    String jsonPayload = RestContext.request.requestBody.toString();
    JsonToLeadDataClass jsonFile = (JsonToLeadDataClass)JSON.deserialize(jsonPayload, JsonToLeadDataClass.class);

    ...
}

Then something like this in your test:

public static testMethod void testPostRestService () {

    JsonToLeadDataClass outerJsonObj = new JsonToLeadDataClass();
    outerJsonObj.leadName = 'hello lead';
    outerJsonObj.city = 'Bang';
    outerJsonObj.address = 'dsadaa';
    outerJsonObj.company = 'saasasd';
    outerJsonObj.country = 'India';
    outerJsonObj.email = 'abc@dgmail.com';
    outerJsonObj.phone = '09139saa828';
    outerJsonObj.state = 'Karnatka';

    List<JsonToLeadDataClass.booking_data> innerJsonObj = new List<JsonToLeadDataClass.booking_data>();

    JsonToLeadDataClass.booking_data obj = new JsonToLeadDataClass.booking_data();
    obj.booking_date = 'Mon Jan 15,2018';
    obj.booking_id = 123;
    obj.end_time = '12:00 PM';
    obj.start_time = '12:00 AM';
    obj.centre_name = 'abc';
    obj.guest_name = 'abcxyz';
    obj.seats = 432;
    obj.room_name = 'bdkaskja';
    innerJsonObj.add(obj);
    outerJsonObj.booking_data = innerJsonObj;

    // This gives us our JSON payload to send
    String jsonReq = JSON.serialize(outerJsonObj);
    System.debug('json string is: ' + jsonReq);


    RestRequest req = new RestRequest();
    RestResponse res = new RestResponse();
    req.requestURI = 'https://cs57.salesforce.com/services/apexrest/Lead/'; 
    req.httpMethod = 'POST';

    // Set the body to the originally serialized JSON, not a serialized version of the deserialized map of the 
    // previously serialized JSON
    req.requestBody = Blob.valueOf(jsonReq);
    System.debug('req.requestBody is: ' + req.requestBody);
    RestContext.request = req;
    RestContext.response = res;

    // We're sending JSON so we should set the content type accordingly
    RestContext.request.addHeader('Content-Type', 'application/json');

    System.debug('rest context request is: ' + RestContext.request);

    Test.startTest();
    NucleusAPI.createLeadAPI();
    Test.stopTest();
}

I don't think there should be any need to put things in the parameters of the request.

Related Topic