Testing Custom Controllers and Controller Extensions

Controller extensions and custom controllers, like all Apex scripts, should be covered by unit tests. Unit tests are class methods that verify whether a particular piece of code is working properly. Unit test methods take no arguments, commit no data to the database, and are flagged with the testMethod keyword in the method definition.

When writing unit tests for controller extension and custom controller classes, you can set query parameters that can then be used in the tests. For example, the following custom controller and markup is based on the example from Controller Methods, but has been extended to expect the following query parameter in the URL for the page: ?qp=yyyy. A test method class follows, which exercises the functionality of this page:

public class thecontroller {

            private String firstName;
            private String lastName;
            private String company;
            private String email;
            private String qp;

            public thecontroller() {
                this.qp = ApexPages.currentPage().getParameters().get('qp');
            }

            public String getFirstName() {
                  return this.firstName;
            }

            public void setFirstName(String firstName) {
                  this.firstName = firstName;
            }

            public String getLastName() {
                  return this.lastName;
            }

            public void setLastName(String lastName) {
                  this.lastName = lastName;
            }

            public String getCompany() {
                  return this.company;
            }

            public void setCompany(String company) {
                  this.company = company;
            }

            public String getEmail() {
                  return this.email;
            }

            public void setEmail(String email) {
                  this.email = email;
            }

            public PageReference save() {
                PageReference p = null;
                
                if (this.qp == null || !'yyyy'.equals(this.qp)) {
                    p = Page.failure;
                    p.getParameters().put('error', 'noParam');
                } else {
                    try {
                        Lead newlead = new Lead(LastName=this.lastName, 
                                                FirstName=this.firstName, 
                                                Company=this.company, 
                                                Email=this.email);
                        insert newlead;
                    } catch (Exception e) {
                        p = Page.failure;
                        p.getParameters().put('error', 'noInsert');
                    }
                }
                
                if (p == null) {
                    p = Page.success;
                }
                
                p.setRedirect(true);
                return p;
            }
 }
The controller calls two additional pages: a success page and a failure page. The text of those pages is not important for this example. They merely have to exist.

The following markup uses the controller above:

<apex:page controller="thecontroller" tabstyle="lead">
   <apex:pageBlock>
      <apex:form>
         <h1>Test page for adding leads</h1>
         <p>This is a test page for adding leads.</p>
         <p>First name: <apex:inputText value="{!FirstName}"></apex:inputText></p>
         <p>Last name: <apex:inputText value="{!LastName}"></apex:inputText></p>
         <p>Company: <apex:inputText value="{!Company}"></apex:inputText></p>
         <p>Email address: <apex:inputText value="{!Email}"></apex:inputText></p>
         <apex:commandButton action="{!save}" value="Save New Lead"/>
      </apex:form>
   </apex:pageBlock>
</apex:page>

The following class tests the controller:

@isTest
                    
public class thecontrollerTests { public static testMethod void testMyController() { PageReference pageRef = Page.success; Test.setCurrentPage(pageRef); thecontroller controller = new thecontroller(); String nextPage = controller.save().getUrl(); // Verify that page fails without parameters System.assertEquals('/apex/failure?error=noParam', nextPage); // Add parameters to page URL ApexPages.currentPage().getParameters().put('qp', 'yyyy'); // Instantiate a new controller with all parameters in the page controller = new thecontroller(); controller.setLastName('lastname'); controller.setFirstName('firstname'); controller.setCompany('acme'); controller.setEmail('firstlast@acme.com'); nextPage = controller.save().getUrl(); // Verify that the success page displays System.assertEquals('/apex/success', nextPage); Lead[] leads = [select id, email from lead where Company = 'acme']; System.assertEquals('firstlast@acme.com', leads[0].email); } }
Tip
If you are testing your controller you may see the following error message:
Method does not exist or incorrect signature: Test.setCurrentPage(System.PageReference)
If this message appears, look to see if you have created a class called Test. If you have, rename the class.
© Copyright 2000–2014 salesforce.com, inc. All rights reserved.
Various trademarks held by their respective owners.