[SalesForce] Test coverage on controller were all functions return null or void

I've only written a few test classes. Each time I've achieved 100%, it involved functions that took args and returned some type of value. How do I test a controller with functions that do not have parameters and return null or are void? Please, I'm not asking to write my code coverage, just push me in the right direction. Here is the controller

public with sharing class AddAccountsToNSOppController {

  // the soql without the order and limit
  private String soql {get;set;}
  // the collection of accounts to display
  public List<aAccount> accounts {get;set;}

  public List<aAccount> accountList {get;set;}

  public Id currentOppId{get; set;}

  public Integer numberOfAccounts {get;set;}


 // init the controller and display some sample data when the page loads
  public AddAccountsToNSOppController(ApexPages.StandardController controller) {

    currentOppId = controller.getId();
    soql = 'select Name, Parent.Name, BillingState, BillingCity, Near_Site_Opportunity__r.Id FROM Account';
    runQuery();
  }

  public class aAccount {
    public Account acc {get; set;}
    public Boolean selected {get; set;}

    public aAccount(Account a) {
        acc = a;
        selected = false;
    }  
 }


  public PageReference proccessSelected() {
    List<Account> selectedAccounts = new List<Account>();


      if(accountList == null) {
          accountList = new List<aAccount>();
          for(Account a : Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20')) {
              accountList.add(new aAccount(a));
          }
      }


      for(aAccount aAcc : accountList) {
          if(aAcc.selected == true) {
              selectedAccounts.add(aAcc.acc);
          }
      }  

      for(Account a : selectedAccounts) {
          a.Near_Site_Opportunity__c = currentOppId;
      }

      update selectedAccounts;
      numberOfAccounts = selectedAccounts.size();
      selectedAccounts=null;
      return null;
  }

  // the current sort direction. defaults to asc
  public String sortDir {
    get  { if (sortDir == null) {  sortDir = 'asc'; } return sortDir;  }
    set;
  }

  // the current field to sort by. defaults to name
  public String sortField {
    get  { if (sortField == null) {sortField = 'name'; } return sortField;  }
    set;
  }

  // format the soql for display on the visualforce page
  public String debugSoql {
    get { return soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20 ' + currentOppId; }
    set;
  }

  // toggles the sorting of query from asc<-->desc
  public void toggleSort() {
    // simply toggle the direction
    sortDir = sortDir.equals('asc') ? 'desc' : 'asc';
    // run the query again
    runQuery();
  }

  // runs the actual query
  public void runQuery() {

    try {

          accountList = new List<aAccount>();
          for(Account a : Database.query(soql + ' order by ' + sortField + ' ' + sortDir + ' limit 20')) {
              accountList.add(new aAccount(a));
          }

      accounts = accountList;
    } catch (Exception e) {
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
    }

  }

  // runs the search with parameters passed via Javascript
  public PageReference runSearch() {

    String accountName = Apexpages.currentPage().getParameters().get('accountName');

    soql = 'select Name, Parent.Name, BillingCity, BillingState, Near_Site_Opportunity__r.Id FROM Account';

    if (!accountName.equals(''))
      soql += ' WHERE Name LIKE \''+String.escapeSingleQuotes(accountName)+'%\''; 

    // run the query again
    runQuery();

    return null;
  }
}

and my test class, what I have so far

@isTest
private class AddAccountsToNSOppControllerTest {

    static testMethod void validate() {
        System.assertEquals(null, AddAccountsToNSOppController.runSearch());
    }
}

Best Answer

When testing methods that do not return anything (and even when they do) test the results of what they do. The end goal is to test functionality not lines. If they do return values, you would still want to assert that whatever was changed in the method happened as it should have and not just assert the return value.

For example

public boolean exampleValue {get;set;}

public static void doSomething(){
       exmaplevalue = true;
}

When you test the above you would assert that exampleValue is equals to true as that is what the method is supposed to accomplish

To take it further, suppose that you have a method that does something based on conditions, you can break up your test methods to test those conditions:

public boolean exampleValue {get;set;}

public static void doSomething(){
       exampleValue = someCondition ? true : false;
}

You could create two test methods, one for the false outcome and one for the true outcome.

private static testmethod void trueExample(){
     ...someCondition = true;
     ...doSomething();
     system.assertEquals(true,...exampleValue,'The example value was not set properly');
}

private static testmethod void falseExample(){
     ...someCondition = false;
     ...doSomething();
     system.assertEquals(false,...exampleValue,'The example value was not set properly');
}

If you think through your test methods like you are testing the process and keep yourself in that frame of mind you will be able to write more functional and appropriate test methods.

Related Topic