3

I am trying to test the server side Controller in Apex test. The controller makes a call out to get account information and returns the response in an Object format to lightning component.

The controller looks like following:

public with sharing class AccountsController {
   @AuraEnabled
   public static List<Account> getAccounts(Id recordId){
       RestAPIService service = new RestAPIService();
       List<Account> lstAccount = service.getAccountsForUser(recordId);

       return lstAccount;
   }
}

This has more complex code, I have shortened it for this example.

Code of getting accounts in RestAPIService

public List<Account> getAccountsForUser(Id recordId)
{
  HttpResponse res;
  HttpRequest req = new HttpRequest();
  try{
     // Set HttpRequest params along with the URL.

      res = new Http().send(req);

      String strResponse = res.getBody();

      // private method convert the string JSON to List<Account> lstAccount.
      return lstAccount;
   } catch(Exception e){
   // log exception
   }
}

The AccountsControllerTest looks like following:

@isTest
public class AccountsControllerTest{
 static testMethod void testGetAccounts() {
   Test.startTest();
   Test.setMock(HttpCalloutMock.class, new AccountsInfoCalloutMock());

   // create account for testing.
   Account testAccount1 = new Account(Mandatory params to create an account);
   insert testAccount1;

   List<Account> lstAccount = AccountsController.getAccounts(testAccount1.id);

   Test.stopTest();  

   System.assertEquals(1, lstAccount.size());     
 }
}

This is how the AccountsInfoCalloutMock looks like

@isTest
global class AccountsInfoCalloutMock implements HttpCalloutMock {

   global HTTPResponse respond(HTTPRequest req) {
      System.debug('In AccountsInfoCalloutMock.respond() method.');
      HTTPResponse res = new HTTPResponse();
      /*
        Code to mock HTTP 200 response. There are two callouts one to get the token and another to get account data after passing the token. I have an if condition to set responses for both the calls.
       */
      return res;
   }

} 

The problem is I do not see the System.debug statement in the logs. The Apex test somehow is either not recognizing the mock callout class or the respond method. I tried with removing the @isTest annotation from the mock class but no avail.

  • (1) typically, i place my mock classes as public inner classes inside the testmethod though that won;t be your issue; (2) your test class never inserts the Account - is that important to service.getAccountsForUser(recordId) ? Otherwise, the callout may never be executing – cropredy Nov 17 '17 at 4:52
  • @cropredy In the actual code it does. This is a watered down version of the code. I would see a different exception if that were to happen such as validations. I will update the above code now. – Json Bourne Shell Nov 17 '17 at 6:06
  • you should also post the code for service.getAccountsForUser (bare, essential minimum of course) – cropredy Nov 17 '17 at 6:11
2

The caveat was in the test one should create test data before the Test.startTest() method. It worked for me like that.

New code:

@isTest
public class AccountsControllerTest{
   static testMethod void testGetAccounts() {

    // create account for testing.
    Account testAccount1 = new Account(Mandatory params to create an account);
    insert testAccount1;

    Test.startTest();
    Test.setMock(HttpCalloutMock.class, new AccountsInfoCalloutMock());

     List<Account> lstAccount = 
     AccountsController.getAccounts(testAccount1.id);

     Test.stopTest();  

     System.assertEquals(1, lstAccount.size());     
    }
   }

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.