[SalesForce] Assertion in the Test Class for ApexRest

I have a Apex Class which is exposed as a Rest API, the method is current void like below

@RestResource(urlMapping='/SFDataAPI/*')
global with sharing class SFDataAPI {    
    @HttpGet
    global static void doGet() {
        String result = '';
        RestRequest req = RestContext.request;
        String segmentID = req.params.get('SegmentID');
        List<Account> accs = [SELECT Name,Parent.Name FROM Account WHERE  Data_Source_ID__c =  :segmentID ];
        Account acc = accs[0];
            Map<String,String> resultMap = new Map<String,String> {
                'Site Account Name' => acc.Name,
                    'Parent Account Name'=> acc.Parent.Name
                    };
        result = JSON.serialize( resultMap);
        RestContext.response.addHeader('Content-Type','application/json');
        RestContext.response.responseBody = Blob.valueOf(result);
        }   
}

I tried writing my Test class like below

@IsTest
public class SFDataAPITest {
    @IsTest static void testUnit1()
    {
        Test.startTest();
        RestRequest req = new RestRequest(); 
        RestResponse res = new RestResponse();
        req.requestURI = '/services/apexrest/SFDataAPI'; 
        req.params.put('SegmentID', 'TestPAX123');
        req.httpMethod = 'GET';
        req.addHeader('Content-Type', 'application/json'); 
        RestContext.request = req;
        RestContext.response = res;
         SFDataAPI.doGet();
        //System.debug();
        Test.stopTest();          
    }
 }

I not able to do the assertion here because when I try assign the response from the API in to the String or list throws error saying Illegal assignment from void to Account or Illegal assignment from void to String how can I handle that here.

Best Answer

Instead of using return value, you can directly use the RestContext response.

As per the documentation here below is true for responseBody property of RestResponse class

The response is either the serialized form of the method return value or it's the value of the responseBody property based on the following rules:

  • If the method returns void, then Apex REST returns the response in the responseBody property.
  • If the method returns a value, then Apex REST serializes the return value as the response.

Below is the sample code to get the assert statements working

Test.startTest();
RestRequest req = new RestRequest(); 
RestResponse res = new RestResponse();

req.requestURI = '/services/apexrest/SFDataAPI'; 
req.params.put('name', 'ABC');
req.httpMethod = 'GET';
req.addHeader('Content-Type', 'application/json'); 

RestContext.request = req;
RestContext.response = res;

SFDataAPI.doGet();
res = RestContext.response; //Set the response here

String actual = res.responseBody.toString(); //Convert Blob to String
String expected = '{"Parent Account Name":null,"Site Account Name":"ABC"}'; //Your expected output
System.assertEquals(actual, expected);
System.assertEquals(200,res.statusCode); //Assert with expected status code. Status Code needs to be set in the main class.
Test.stopTest(); 

Also, you will have to create test Acount record with the matching SegmentID. So that the doGet method returns a record when the SOQL executes.

Hope this helps!

Related Topic