[SalesForce] Code coverage for @HttpGet / Rest method

i'm trying to do a test method to cover a @HttpGet method. I'm pretty new on apex and i don't really understand how test (method/class) works for this kind of things.

Here is my method :

@RestResource(urlMapping='/invoicingWS')
global  class InvoicingWS {
public class WsException extends Exception {}

  @HttpGet
  global static void doInvoice() {
    RestContext.response.addHeader('Content-Type', 'application/json');
    try {
        Map<String,String> data = RestContext.request.params;
        if(!data.containsKey('companyID')) throw new WsException('companyID Missing');
        if(!data.containsKey('maxDate')) throw new WsException('maxDate Missing');

        Date maxDate = Date.valueOf(data.get('maxDate'));
        Date minDate;
        if(data.containsKey('minDate')) {
            minDate = Date.valueOf(data.get('minDate'));
            if(minDate > maxDate) throw new WsException('Input error: minDate > maxDate');
        }

        Id orderId  = [SELECT Id FROM Order WHERE Account.CompanyID__c = :data.get('companyID') LIMIT 1].Id;
        Invoicing_BuildInvoiceData x = new Invoicing_BuildInvoiceData(orderId, minDate, maxDate);
        Database.executeBatch(x);

        RestContext.response.responseBody = Blob.valueOf( '{ "status" : "success" }');
    } catch (QueryException d) {
        RestContext.response.responseBody = Blob.valueOf( '{ "status" : "error", "detail" : "Company does not exist"}');
    } catch (Exception e) {
        RestContext.response.responseBody = Blob.valueOf( '{ "status" : "error", "detail" : "'+e.getMessage()+'"}');
    }
  }
}

I tried to realize a corresponding test method but it does not work. Here is my work :

Test Method

    static testMethod void doInvoice(){

    RestRequest req = new RestRequest(); 
    RestResponse res = new RestResponse();

    req.requestURI = 'https:/services/apexrest/invoicingWS';
    req.addHeader('Content-Type', 'application/json');
    req.httpMethod = 'GET';
    req.requestBody = Blob.valueof('{}');

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

    InvoicingWS.doInvoice();

}

I know i miss so skills in Code coverage but i'm really not able to do it really quickly and that's why i request your help to do this.

Thanks in advance for answers

Best Answer

You are actually really close... The short version is that you test your @RestResource Class just like you would any other Class.

  1. ARRANGE - setup the RestRequest & Instanciate the Class
  2. ACT - invoke the method, and capture the response in a local variable
  3. ASSERT - Run your assertions against the response local variable

(Don't need mocks for for Apex REST Resources, just for when calling a service outside of Salesforce)

static testMethod void test_doInvoice(){
    //ARRANGE - setup request like the external system would....
    RestRequest req = new RestRequest(); 
    RestResponse res = new RestResponse();
    InvoicingWS classToTest = new InvoicingWS();

    req.requestURI = 'https://cs84.salesforce.com/services/apexrest/invoicingWS';

    req.addHeader('Content-Type', 'application/json');
    req.httpMethod = 'GET';
    req.requestBody = Blob.valueof('{}');

    RestContext.request = req;
    RestContext.response= res;
    
    
    //ACT - make the request from inside the test execution context, rather than from the external system
    Test.startTest();
    res = classToTest.doInvoice();
    Test.stopTest();

    //ASSERT - verify that you got what you expected...
    String actualValue = res.getBody();
    String expectedValue = '{ "status" : "success" }'; //from your @HttpGet method above....
    System.assertEquals(actualValue, expectedValue);
    System.assertEquals(200, res.getStatusCode());

}
Related Topic