5

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.

3
  • (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, 2017 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. Nov 17, 2017 at 6:06
  • you should also post the code for service.getAccountsForUser (bare, essential minimum of course)
    – cropredy
    Nov 17, 2017 at 6:11

1 Answer 1

5

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());     
    }
   }

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .