3

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

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.

  • The exampleValue and doSomething(), I can create those in the test class? – Tyler Zika Sep 6 '16 at 17:38
  • They are examples, for illustration of my point. If you really want a property named exampleValue feel free to create it. Same with a method named doSomething(). Ultimately what you call properties and methods is up to you. – Eric Sep 6 '16 at 17:40
  • Still not clicking. Could you give me one example from my class? – Tyler Zika Sep 6 '16 at 17:58
  • 2
    The examples I gave are the most basic possible. If you read through my post you will hopefully get what I am saying. You want to test results, processes, etc not lines of code. What is your code doing, test that. From your method processSelected you will want to assert that numberOfAccounts is the correct value. Additionally, you will want to query the account records and assert that the values were updated as expected. That is what you are testing. The coverage will come organically – Eric Sep 6 '16 at 18:16
1

just call the method and use assert to check value of global variables like

@isTest
private class AddAccountsToNSOppControllerTest {

    static testMethod void validate() {
        AddAccountsToNSOppController cont = new AddAccountsToNSOppController ();
        cont.proccessSelected();
        System.assert(cont.accountList.size() > 0)
    }
}

But to satisfy the condition you also need to create test data in your test methods.

  • 2
    And where are you getting accountList from, exactly? – Adrian Larson Sep 6 '16 at 17:08

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.