0

I am trying to write a test class for a @AuraEnabled Apex Class. But I can not get it to pass. The first thing is you can not return an HTTPRequest or Response to a @AuraEnabled Class so I can not match the types from the Test to the Main Class. Any Help getting this code to pass would be greatly appreciated.

Main Class


public class APICaller{
@AuraEnabled

public static String CallApi(){

HttpRequest req = new HttpRequest();
                      req.setEndpoint({MY-URL-ENDPOINT});
                      req.setMethod('POST'); 
                      req.setHeader('Content-Type', 'application/json');
                      req.setTimeout(120000);
                      String body = '{"Username":"username"}';
                      req.setBody(body);
                      Http http = new Http();
                      HTTPResponse res = http.send(req);
                      return res.getBody();
    }

}

Test Class


@isTest
public class KonnectidAlpha_GetClients_Test{

@isTest  public static void CallTestApi(){

// Associate the callout with a mock response
Test.setMock(HttpCalloutMock.class, new HttpCalloutMockClass());

    // Call method to test
  String response = APICaller.CallApi();
  System.debug(response);
  String actualValue =  response;
  String expectedValue = '{"response": "Records Synced"}';
  System.assertEquals(actualValue, expectedValue);

 } 
}

HTTPCalloutMock Class


@isTest
global class HttpCalloutMockClass implements HttpCalloutMock {
// Implement this interface method

global HTTPResponse respond(HTTPRequest request) {
    // Create a fake response
    HttpResponse response = new HttpResponse();
    response.setHeader('Content-Type', 'application/json');
    String body = '{"response": "Records Synced"}';
    response.setBody(body);
    response.setStatusCode(200);
    return response; 
  }
}
  • just like any other test. Ignore the AuraEnabled. The only hack you need is if you are throwing an AuraHandledException not sure why you need the aura class to return an http response your code seems like it should pass where is the issue specifically along with error message – Eric Aug 26 '17 at 5:03
  • I get an error if I try to return a HttpResponse to a @AuraEnabled class. I thought it would pass also but no go. It is the one thing blocking me from releasing my app. – IOG Aug 26 '17 at 5:28
  • I reference this article to create this trailhead.salesforce.com/trails/force_com_dev_intermediate/… – IOG Aug 26 '17 at 5:29
2

The code you posted in your question passes with 100% coverage in my developer org when copied verbatim, except for changing {MY-URL-ENDPOINT} to a real String.

As a sanity test, I also wrote a unit test of my own, included below.

public class q190011 {
    @AuraEnabled public static String doRequest() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://www.google.com/');
        req.setMethod('GET');
        return (new Http().send(req)).getBody();
    }
}

@isTest class q190011t {
    public class Mock implements HttpCalloutMock {
        public HttpResponse respond(HttpRequest req) {
            HttpResponse res = new HttpResponse();
            res.setBody('OKAY!');
            res.setStatus('OK');
            res.setStatusCode(200);
            return res;
        }
    }
    @isTest static void test() {
        Test.setMock(HttpCalloutMock.class, new Mock());
        String result = q190011.doRequest();
        System.assertEquals('OKAY!', result);
    }
}

As you can see, there's no particular magic for an @AuraEnabled method as opposed to any other type of method. Everything included in your question is correctly written as-is.

Remember that your mock is not returning a HttpResponse "directly" to the live code, but does so through the Http.send call. Your @AuraEnabled method should indeed be returning a String or some other "normal" type, but not an HttpRequest or HttpResponse directly.

The only "problem" that you have in the code you've posted is that the actual arguments to System.assertEquals should be expectedValue, actualValue. Reversing the order of the parameters will lead to some confusion if your tests fail on that assertion, because the error message will read differently than you expect.

  • So this code does work by itself but when I apply it to my real class it fails with this error System.ListException: List index out of bounds: 0 – IOG Aug 26 '17 at 16:11
  • I have narrowed the issue down to req.setBody. If I set the body to req.setBody('OK'); it works but if if put in the JSON string I need it breaks req.setBody('{"Username":"'+SettingsList[0].Username__c+'", "Password" : "'+SettingsList[0].Password__c+'", "SiteIDs": "'+SettingsList[0].SiteIDs__c+'", "orgId" : "'+orgId+'", "userId": "'+userId+'"}'); – IOG Aug 26 '17 at 17:41
  • @IOG That wasn't in your original code. By the way, you should not be constructing your own JSON; use JSON.serialize instead. And, of course, verify that your SettingsList is not empty first. – sfdcfox Aug 26 '17 at 17:43
  • I was wrong it is not the serialization when I go back to the code break on simply adding this variable userName = SettingsList[0].Username__c; – IOG Aug 27 '17 at 1:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.