Apex HttpCalloutMock DML workaround

When doing a callout it has to happen before the DML action. If it happens after the DML it will throw an error or will not execute. Workaround I used is to manually keep track of the mock response, and call the respond method to intercept Http.send when running a test. By checking for Test.isRunningTest() && (mock!=null) we can send the mock response.

Checking for test running and returning mock response

	public static HttpCalloutMock mock = null;
	public HttpResponse callApiEndpoint(String apiEndpoint, String method, Object aPayload) {
		HttpRequest req = new HttpRequest();
    try {
      if (apiEndpoint != null) {
        req.setTimeout(120000);
        req.setMethod(method);
        setAuthHeader(req);
        req.setEndpoint(WebCustomSettings.Heroku_API_URL__c + apiEndpoint);
				if (aPayload!=null)
        	req.setBody(String.valueOf(aPayload));
        System.debug('Sending api request to endpoint' + apiEndpoint);
				if (Test.isRunningTest() && (mock!=null)) {
					 return mock.respond(req);
			 	} else {
					Http http = new Http();
	        return http.send(req);
				}

      } else {
        System.debug('Service apiEndpoint and payload must not be null');
        throw new Rest_Exception(ResponseCodes_Mgr.getCode('HEROKU_REQUEST_CALLOUT_FAILED'));
      }
    } catch (Exception ex) {
      System.debug('ERROR sending sync request to Heroku: ' + ex);
      List<String> theArgs = new List<String>();
      theArgs.add('Api');
      theArgs.add(req.getEndpoint());
      throw new Rest_Exception(ResponseCodes_Mgr.getCode('HEROKU_REQUEST_CALLOUT_FAILED', ex, theArgs));
    }
  }

Test class

  Test.startTest();
        System.runAs(new User(Id=userWithAccountContact.get('UserId'))){
          //Setting the mock variable and it's also a test so will return the mock response
          Heroku_Services_Api.mock = new Heroku_Services_Api_Mock(200, 'Complete', '{}',null);
          req.requestBody = Blob.valueOf('{"id":"'+ account.Id +'", "clientId":"' + userWithAccountContact.get('ContactId') + '", "amount":122233,"endDate":"2022-01-01"}');
          req.requestURI = '/v1/account';
          req.httpMethod = 'PATCH';
          RestContext.request = req;
          RestContext.response = res;

          try{
            Rest_Dispatcher.doPatch();
          } catch(Rest_Exception ex){
            System.assertEquals(ex.itsRespCode.formattedSystemMessage, 'blah');
          }

          System.assert(res.responseBody!=null);
          System.assertEquals(res.statusCode, 200);
      }
      Test.stopTest();
Advertisements

One Comment on “Apex HttpCalloutMock DML workaround

  1. I must say it was hard to find your blog in google.
    You write awesome articles but you should rank your page higher
    in search engines. If you don’t know how to
    do it search on youtube: how to rank a website Marcel’s way

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: