I have a very weird issue related to an Apex RestResource that I can't seem to wrap my head around.
I have an Apex class defined as a RestResource and am trying to test the functionality. In one particular sandbox (passes in 3 others), simply wrapping the call in Test.startTest/Test.stopTest causes the RestContext.response property to be set to null.
Here's what I have in a nutshell:
@HttpPost
public static void routeAndProcessRequest(){
try{
RestContext.response.responseBody = response; // processing code omitted for simplicity
RestContext.response.addHeader('Content-Type', 'application/json');
RestContext.response.statusCode = 200;
}catch(Exception e){
// handle errors
}
}
Here is my test method:
RestContext.request = new RestRequest();
RestContext.response = new RestResponse();
RestContext.request.requestURI = 'some/url/here';
RestContext.request.httpMethod = 'POST';
Test.startTest();
ApexRestResource.routeAndProcessRequest();
Test.stopTest();
System.assertEquals(200, RestContext.response.statusCode, 'Should be a 200 response code');
System.assertNotEquals(null, RestContext.response.responseBody, 'Response should not be null');
Simply the presence of Test.start/stopTest causes System.assertEquals(200, RestContext.response.statusCode, 'Should be a 200 response code');
to throw an Attempt to de-reference a null object
exception. If Test.start/stopTest is removed or commented out from the method, everything passes with flying colors.
Examining the debug logs, everything appears to operate exactly as expected until the asserts are reached. I even see the line executing where addHeader is called so the response is not null there.
I should note I have a number of test methods for different features of the same RestResource that do not have this issue (and as mentioned, the method in question executes without a hitch in all other environments it's been run in).
What could be happening here?
Edit: Adding some additional context in hopes it may help. The logic I'm trying to test creates an object that has a lot of automation on it. Not sure if this matters. Additionally, I've noticed something in the debug logs that seems off.
17:38:23.746 (40757223556)|VARIABLE_SCOPE_BEGIN|[3]|System.RestContext.request|System.RestRequest|true|true
17:38:23.746 (40757233184)|VARIABLE_SCOPE_BEGIN|[4]|System.RestContext.response|System.RestResponse|true|true
17:38:23.746 (40757266024)|HEAP_ALLOCATE|[776]|Bytes:112
17:38:23.746 (40757274184)|HEAP_ALLOCATE|[776]|Bytes:5
17:38:23.746 (40757305313)|SYSTEM_METHOD_ENTRY|[1]|RestContext.RestContext()
17:38:23.746 (40757310157)|STATEMENT_EXECUTE|[1]
17:38:23.746 (40757324175)|SYSTEM_METHOD_EXIT|[1]|RestContext
17:38:23.746 (40757463408)|STATEMENT_EXECUTE|[778]
17:38:23.746 (40757501199)|HEAP_ALLOCATE|[778]|Bytes:38
17:38:23.746 (40757547957)|STATEMENT_EXECUTE|[780]
17:38:23.746 (40757571113)|HEAP_ALLOCATE|[780]|Bytes:156
17:38:23.746 (40757577791)|HEAP_ALLOCATE|[780]|Bytes:10
17:38:23.746 (40757588229)|SYSTEM_METHOD_ENTRY|[1]|RestResponse.RestResponse()
17:38:23.746 (40757592730)|STATEMENT_EXECUTE|[1]
17:38:23.746 (40757599599)|SYSTEM_METHOD_EXIT|[1]|RestResponse
When Test.start/stopTest are omitted, this block shows up in the debug log once when the request/response is instantiated before startTest. With Test.start/stopTest present, this same block also appears in the log after Test.stopTest executes. It seems to 'reset' the values (?) so anything done by the RestResource apex class is lost.