[SalesForce] Continuation Apex Unit Testing – Lightning

With Summer'19 release continuation is available in Lightning. To make long running callouts.

Continuation – Aura Dev Guide:
https://developer.salesforce.com/docs/atlas.en-us.220.0.lightning.meta/lightning/apex_continuations.htm?search_text=COntinuation

Documentation only provides how to use continuation in Apex Controller. But it does not provide any sample code for Unit Test Coverage.

As per the documentation the callback method should be static with list of labels and state as arguments.
But if we use the existing testing framework for continuation test coverage. If we pass object of Controller in ‘invokeContinuationMethod’ it throws error that callback method does not exist…because callback method is static and object of controller can not call static method…then what is workaround?

Here is the similar stack exchange question which states it as testing framework gap: How to create controller class instance to pass it as argument of 'Test.invokeContinuationMethod' while Callback method is Static

Apex Class:

public class ContinuationSampleCode {
private static final String LONG_RUNNING_SERVICE_URL ='callout:MockService';

// Action method
@AuraEnabled(continuation=true cacheable=true)
public static Object startRequest() {
  // Create continuation. Argument is timeout in seconds.
  Continuation con = new Continuation(40);
  // Set callback method
  con.continuationMethod='processResponse';
  // Set state
  con.state='Hello, World!';
  // Create callout request
  HttpRequest req = new HttpRequest();
  req.setMethod('GET');
  req.setEndpoint(LONG_RUNNING_SERVICE_URL);
  // Add callout request to continuation
  con.addHttpRequest(req);
  // Return the continuation
  return con;
}

// Callback method
@AuraEnabled(cacheable=true)
public static Object processResponse(List<String> labels, Object state) {
  // Get the response by using the unique label
  HttpResponse response = Continuation.getResponse(labels[0]);
  // Set the result variable
  String result = response.getBody();
  return result;
}}

Apex Test Class:

@isTest private class ContinuationSampleCode_Test {
@isTest private static void startRequestTest() {
        Test.startTest();
        HttpResponse response = new HttpResponse();
        response.setBody('Mock response body');   
        Continuation conti = (Continuation)ContinuationSampleCode.startRequest();
            // Set the fake response for the continuation     
            Test.setContinuationResponse('continuation-1', response);
            // Invoke callback method
            Object result = Test.invokeContinuationMethod(new ContinuationSampleCode(), conti);    
        Test.stopTest();
        system.assert(result!=null);
}
}

Already created with SFDC Support. Waiting for response from them.

Looking for solution on this.
Appreciate your time and help.

Best Answer

I tried making few changes to your code and this may be a solution although it does require adding an additional method in your main class.

Apex Class :

    public class ContinuationSampleCode {
    private static final String LONG_RUNNING_SERVICE_URL ='callout:MockService';
    // Action method
    @AuraEnabled(continuation=true cacheable=true)
    public static Object startRequest() {
      // Create continuation. Argument is timeout in seconds.
      Continuation con = new Continuation(40);
      // Set callback method
      con.continuationMethod='processResponse';
      // Set state
      con.state='Hello, World!';
      // Create callout request
      HttpRequest req = new HttpRequest();
      req.setMethod('GET');
      req.setEndpoint(LONG_RUNNING_SERVICE_URL);
      // Add callout request to continuation
      con.addHttpRequest(req);
      // Return the continuation
      return con;
    }

    // Callback method
    @AuraEnabled(cacheable=true)
    public static Object processResponse(List<String> labels, Object state) {
      // Get the response by using the unique label
      HttpResponse response = Continuation.getResponse(labels[0]);
      // Set the result variable
      String result = response.getBody();
      return result;
    }


    public static Object processResponse() {
        List<String> labels = new list<String>();
        labels.add('continuation-1');
        object result =  processResponse(labels,null);
        return result;
    }

    }

Test Class // test class

    @isTest private class ContinuationSampleCode_Test {
    @isTest private static void startRequestTest() {
            Test.startTest();
            HttpResponse response = new HttpResponse();
            response.setBody('Mock response body');   
            Continuation conti = (Continuation)ContinuationSampleCode.startRequest();
                // Set the fake response for the continuation     
                Test.setContinuationResponse('continuation-1', response);
                // Invoke callback method
                Object result = Test.invokeContinuationMethod(new ContinuationSampleCode(), conti);    
                Test.stopTest();
            system.assert(result!=null);
    }
    }
Related Topic