In this chapter, we will cover the following recipes:
Overriding standard buttons
Data-driven styling
Turning off an action poller
Visualforce in the sidebar
Passing parameters to action methods
Reacting to URL parameters
Passing parameters between Visualforce pages
Opening a pop-up window
Adding a launch page
Testing a custom controller
Testing a controller extension
This chapter provides solutions for a variety of situations that Visualforce developers are likely to encounter on a regular basis. Enhancing or replacing standard functionality with Visualforce enriches the user experience, improving user productivity and adoption. Visualforce also allows business processes to be highly systemized, guiding users through the creation and the ongoing management of data. Writing effective tests for Visualforce controllers is a key skill that allows developers to deploy Visualforce pages to production, and be confident that they will work as intended.
Two common complaints from users are that the information they are interested in requires a number of clicks to access, or that there is too much information on a single page, resulting in a cluttered layout that requires significant scrolling. This is an area where a Visualforce override can make a significant difference by traversing relationships to display information from a number of records on a single page.
Salesforce allows the standard pages associated with sObject record actions, such as view and edit, to be overridden with Visualforce pages. This is typically used to display the record in a branded or customized format; for example, to display the details and related lists in separate tabs.
In this recipe, we will override the standard page associated with viewing an account record with a Visualforce page that not only provides a tabbed user interface, but also lifts up additional activity information from the related contact list and line item information from the related opportunity lists. Further, the related opportunities displayed will be limited to those which are open.
Note
Only Visualforce pages that use the standard controller for the sObject can override standard pages.
This recipe makes use of a standard controller, so we only need to create the Visualforce page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
AccViewOverride
in the Label field.Accept the default AccViewOverride that is automatically generated for the Name field.
Paste the contents of the
AccViewOverride.page
file from the code download into the Visualforce Markup area and click on the Save button.Then, navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the AccViewOverride page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Now that the Visualforce page is complete, configure the account view override. Navigate to Your Name | Setup | Customize | Accounts | Buttons, Links and Actions.
Locate the View entry on the resulting page and click on the Edit link.
On the following page, locate the Override With entry, check the Visualforce Page radio button, and choose AccViewOverride from the list of available pages.
Click on the Save button.
When a user clicks on an account record link anywhere in Salesforce, the tabbed page with details from related records is displayed, as shown in the following screenshot:

The key areas of the code are the tabs for the related records. The Open Opportunities tab iterates the opportunities related list, and generates an <apex:pageblock />
for each opportunity that is currently open by encapsulating this inside a conditionally rendered <apex:outputPanel />
.
<apex:repeat value="{!Account.Opportunities}" var="opp"> <apex:outputPanel rendered="{!NOT(opp.IsClosed)}"> <apex:pageBlock title="{!opp.Name}">
Then, the standard <apex:relatedList />
component is used to generate the opportunity product list by specifying the current value of the opportunity iterator as the subject of the component.
<apex:relatedList subject="{!opp}" list="OpportunityLineItems" />
A useful technique when creating a custom user interface with Visualforce is to conditionally style important pieces of information to draw the user's attention to them as soon as a page is rendered.
Most Visualforce developers are familiar with using merge fields
to provide sObject field values to output tags, or to decide if a section of a page should be rendered. In the tag shown below, the merge field, {!account.Name}
, will be replaced with the contents of the name field from the account sObject:
<apex:outputField value="{!account.Name}"/>
Merge fields can also contain formula operators and be used to dynamically style data when it is displayed.
In this recipe we will display a table of campaign records and style the campaign cost in green if it was within budget, or red if it was over budget.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
ConditionalColour
in the Label field.Accept the default ConditionalColour that is automatically generated for the Name field.
Paste the contents of the
ConditionalColour.page
file from the code download into the Visualforce Markup area and click on the Save button.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the ConditionalColour page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Opening the following URL in your browser displays the ConditionalColour page: https://<instance>/apex/ConditionalColour
. Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.
A list of campaigns is displayed, with the campaign cost rendered in red or green depending on whether it came in on or over budget.

Conditional styling is applied to the Actual Cost column by comparing the actual cost with the budgeted cost.
<apex:column style="color: {!IF(AND(NOT(ISNULL(campaign.ActualCost)), campaign.ActualCost<=campaign.BudgetedCost), "lawngreen", "red")}" value="{!campaign.ActualCost}"/>
The Data-driven decimal places recipe in Chapter 2, Custom Components shows how to format numeric values to a specified number of decimal places.
The standard Visualforce <apex:actionPoller/>
component sends AJAX requests to the server based on the specified time interval. An example use case is a countdown timer that sends the user to another page when the timer expires. But what if the action poller should stop when a condition in the controller becomes true, for example, when a batch apex job completes or an update is received from a third-party system?
In this recipe, we will simulate the progression of a payment through a number of states. An action poller will be used to retrieve the latest state from the server and display it to the user. Once the payment reaches the state Complete, the action poller will be disabled.
This recipe makes use of a custom controller, so this will need to be created before the Visualforce page.
Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
PollerController.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
ActionPoller
in the Label field.Accept the default ActionPoller that is automatically generated for the Name field.
Paste the contents of the
ActionPoller.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the ActionPoller page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Opening the following URL in your browser displays the ActionPoller page: https://<instance>/apex/ActionPoller
.
Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.
The page polls the server for the current state, displaying the message Polling … when the action poller executes as shown in the following screenshot:

Once the current state reaches Complete, the action poller terminates.
The key to this recipe is the enabled
attribute on the actionPoller
component.
<apex:actionPoller action="{!movePayment}" rerender="payment" interval="5" status="status" enabled="{!paymentState!='Complete'}"/>
Tip
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
This merge field references the paymentState
property from the custom controller, which is evaluated each time the action poller executes until it becomes false. At this time the action poller is permanently disabled.
The
Polling … message is generated by the actionStatus
component associated with the action poller. This component has a startText
attribute but not a stopText
attribute, which means that the text will only be displayed while the AJAX request is in progress.
<apex:actionStatus startText="Polling ..." id="status"/>
The Using action functions recipe in Chapter 7, JavaScript shows how to execute a controller.
Visualforce is commonly used to produce custom pages that override or supplement standard platform functionality. Visualforce pages can also be incorporated into any HTML markup through use of an iframe.
Note
An iframe, or inline frame, nests an HTML document inside another HTML document. For more information, visit http://reference.sitepoint.com/html/iframe.
In this recipe, we will add a Visualforce page to a Salesforce sidebar component. This page will display the number of currently open cases in the organization, and will be styled and sized to fit seamlessly into the sidebar.
This recipe makes use of a custom controller, so this will need to be created before the Visualforce page.
Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
CasesSidebarController.cls
Apex class from the code download into the Apex Class area.Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
CasesSidebar
in the Label field.Accept the default CasesSidebar that is automatically generated for the Name field.
Paste the contents of the
CasesSidebar.page
file from the code download into the Visualforce Markup area.Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the CasesSidebar page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Next, create the home page component by navigating to the Home Page Components setup page by clicking on Your Name | Setup | Customize | Home | Home Page Components.
Scroll down to the Custom Components section and click on the New button.
If the Understanding Custom Components information screen appears, as shown in the following screenshot, click on the Next button.
On the next page, Step 1. New Custom Components, enter
Case Count by Status
in the Name field, select the HTML Area option, and click on the Next button.On the next page, Step 2. New Custom Components, select the Narrow (Left) Column option.
Select the Show HTML box.
Paste the following markup into the editable area:
<iframe style="border: none" src="/apex/CasesSidebar" seamless=""></iframe>
Click on the Save button.
Next, add the new component to one or more home page layouts. Navigate to Your Name | Setup | Customize | Home | Home Page Layouts.
Locate the name of the home page layout you wish to add the component to and click on the Edit link.
On the resulting page, Step 1. Select the Components to show, select the Case Count by Status box in the Select Narrow Components to Show section and click on the Next button.
On the next page, Step 2. Order the Components, use the arrow buttons to move the Case Count by Status component to the desired position in the Narrow (Left) Column list and click on the Save button.
Repeat steps 22 to 24 for any other home page layouts that will contain the sidebar component.
Navigate to Your Name | Setup | Customize | User Interface and locate the Sidebar section.
Select the Show Custom Sidebar Components on All Pages box as shown in the following screenshot, and click on the Save button.
The component appears in the sidebar on all pages, showing the number of cases open for each nonclosed status, as shown in the following screenshot:

The case counts displayed in the sidebar will be retrieved when the page is displayed, but will remain static from that point. An action poller can be used to automatically refresh the counts at regular intervals. However, this will introduce a security risk, as each time the poller retrieves the updated information it will refresh the user's session. This means that if a user were to leave their workstation unattended, the Salesforce session will never expire. If this mechanism is used, it is important to remind users of the importance of locking their workstation should they leave it unattended.
When developers move to Apex/Visualforce from traditional programming languages, such as Java or C#, a concept many struggle with is how to pass parameters from a Visualforce page to a controller action method.
Passing parameters to an action method is key when a Visualforce page allows a user to manage a list of records and carry out actions on specific records. Without this, the action method cannot determine which record to apply the action to.
In this recipe, we will output a list of opportunities and for each open opportunity, provide a button to update the opportunity status to Closed Won. This button will invoke an action method to remove the list element and will also send a parameter to the controller to identify which opportunity to update.
This recipe makes use of a custom controller, so this will need to be created before the Visualforce page.
Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
ActionParameterController.cls
Apex class from the code download into the Apex Class area.Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
ActionParameter
in the Label field.Accept the default ActionParameter that is automatically generated for the Name field.
Paste the contents of the
ActionParameter.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the ActionParameter page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Opening the following URL in your browser shows the list of currently open opportunities: https://<instance>/apex/ActionParameter
.
Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.

Clicking on the Win button for the Grand Hotels Kitchen Generator opportunity updates the status to Closed Won and redraws the list of opportunities.

The page markup to send the parameter to the controller is as follows:
<apex:commandButton value="Win" action="{!winOpp}" status="status" rerender="opps_pb" rendered="{!opp.StageName!='Closed Won'}"> <apex:param name="oppIdToWin" value="{!opp.Id}" assignTo="{!oppIdToWin}" /> </apex:commandButton>
The <apex:param />
component defines the value of the parameter, in this case, the ID of the opportunity, and the controller property that the parameter will be assigned to – oppIdToWin
.
Note
Note that there is a rerender
attribute on the command button. If this attribute is omitted, making the button a simple postback request, the parameter will not be passed to the controller. This is a known issue with Visualforce as documented in the following knowledge article: http://help.salesforce.com/apex/HTViewSolution?id=000002664&language=en_US.
The property is declared in the controller in a normal way.
public Id oppIdToWin {get; set;}
Finally, the action method is invoked when the button is pressed.
public PageReference winOpp() { Opportunity opp=new Opportunity(Id=oppIdToWin, StageName='Closed Won'); update opp; return null; }
The ID of the opportunity to update is assigned to the oppIdToWin
controller property before the action method is invoked; thus, the action method can simply access the property to get the parameter value.
URL parameters are used to pass information to Visualforce pages that the page or controller can then react to. For example, setting a record ID parameter into the URL for a page that uses a standard controller causes the controller to retrieve the record from the database and make it available to the page.
In this recipe we will create a Visualforce search page to retrieve all accounts where the name contains a string entered by the user. If the parameter name is present in the page URL, a search will be run against the supplied value prior to the page being rendered for the first time.
This recipe makes use of a custom controller, so this will need to be created before the Visualforce page.
Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
SearchFromURLController.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
SearchFromURL
in the Label field.Accept the default SearchFromURL that is automatically generated for the Name field.
Paste the contents of the
SearchFromURL.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the SearchFromURL page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Opening the following URL in your browser retrieves all accounts where the name field contains the text ni
: https://<instance>/apex/SearchFromURL?name=ni
.
Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.

The constructor of the custom controller attempts to extract a value for the parameter Name from the page URL, and if one has been supplied, executes the search.
public SearchFromURLController() { searched=false; String nameStr= ApexPages.currentPage().getParameters().get('name'); if (null!=nameStr) { name=nameStr; executeSearch(); } }
Note
Note that the constructor also sets the value retrieved from the URL into the Name property. This property is bound to the input field on the page, and causes the input field to be prepopulated with the value retrieved from the URL when the page is first rendered.
The action method that executes the search is as follows:
public PageReference executeSearch() { searched=true; String searchStr='%' + name + '%'; accounts=[select id, Name, Industry, Type from Account where name LIKE :searchStr]; return null; }
Tip
Note that searchStr
is constructed by concatenating the search term with the %
wildcard characters; this allows the user to enter a fragment of text rather than full words. Also, note that the concatenation takes place outside the SOQL query and the resulting variable is included as a bind expression in the query. If the concatenation takes place directly in the SOQL query, no matches will be found.
If a user is redirected from one Visualforce page to another and they both share the same controller and extensions, the controller instance will be retained and re-used, allowing the second page to access any information captured by the first.
If the pages do not share the same controller and extensions, the controller instance will be discarded and the second page will have no access to any information captured by the first. If the state needs to be maintained across the pages in this case, it must be encapsulated in the parameters on the URL of the second page.
In this recipe, we will build on the example from the previous recipe to create a Visualforce search page to retrieve all accounts where the name contains a string entered by the user, and provide a way for the user to edit selected fields on all the accounts returned by the search. The record IDs of the accounts to edit will be passed as parameters on the URL to the edit page.
As the search page makes reference to the edit page, the edit page and associated custom controller must be created first.
Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
EditFromSearchController.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
Next, create the edit Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
EditFromSearch
in the Label field.Accept the default EditFromSearch that is automatically generated for the Name field.
Paste the contents of the
EditFromSearch.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the EditFromSearch page and click on the Security link.
On the resulting page, select which profiles should have access and click the Save button.
Next, create the search page by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
SearchAndEditController.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
Next, create the Visualforce page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
SearchAndEdit
in the Label field.Accept the default SearchAndEdit that is automatically generated for the Name field.
Paste the contents of the
SearchAndEdit.page
page from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the SearchAndEdit page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Opening the following URL in your browser retrieves all accounts where the name field contains the string United
: https://<instance>/apex/SearchAndEdit?name=United
.
Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.

Notice that the page contains an Edit button, and clicking on this executes the following action method:
public PageReference edit() { PageReference pr=Page.EditFromSearch; Integer idx=1; for (Account acc : accounts) { pr.getParameters().put('account' + idx, acc.id); idx++; } return pr; }
This method initially creates a page reference for the edit page—EditFromSearch. It then iterates the accounts in the search results and adds an entry to the page reference parameters for the account ID. Each parameter has the name account, concatenated with the index of the result, starting from 1
. This will result in a URL of the form https://<instance>/apex/EditFromSearch?account1=001i0000006OVLIAA4&account2=001i0000006OVLJAA4
.
The EditFromSearch page then renders a form with an editable row per account.

The constructor of EditFromSearchController
that manages the data for the page extracts the IDs from the URL and adds them to a list, starting with account1
, until it hits a parameter index that is not present in the URL.
Integer idx=1; String accStr; do { accStr=ApexPages.currentPage().getParameters(). get('account' + idx); if (accStr!=null) { ids.add(accStr); } idx++; } while (null!=accStr);
The action method that saves the user's edits redirects them to the standard account tab once the save is complete.
return new PageReference('/001/o');
Pop-up browser windows have received mixed reviews in recent years. Originally created before tabbed browsers existed to display additional information without interfering with the page the user had navigated to, they were quickly hijacked and used to display advertisements and spam. Pop ups should be used sparingly in applications and wherever possible in response to an action by the user.
The target attribute can be specified as _blank
on HTML hyperlink tags to open the link in a new window, but all modern browsers allow the user to specify that new windows should be opened as new tabs instead. Also, if the browser does open the URL in a new window, it will be of the same size as the existing window and block most of it. Opening a window in JavaScript allows for fine-grained control over many aspects of the pop-up window, for example, the size, and whether to display a toolbar.
In this recipe we will create a page that renders a list of accounts, displaying a very small subset of fields per row. A link will be provided on each row to allow the user to view full details of the account in a pop-up window.
Note
Note that there is no way to ensure that a browser will display a pop-up window. Pop-up blockers generally allow windows to be opened in response to an action by the user, such as clicking on a link, but it is possible for users to configure their browser to block all pop ups regardless of how they were triggered.
This recipe requires two Visualforce pages to be created: the main page containing the list of accounts and the pop-up window page. The pop-up page is referenced by the main page, so this will be created first.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
Popup
in the Label field.Accept the default Popup that is automatically generated for the Name field.
Paste the contents of the
Popup.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the Setup page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Next, create the main account list page by navigating to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
PopupMain
in the Label field.Accept the default PopupMain that is automatically generated for the Name field.
Paste the contents of the
PopupMain.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the PopupMain page and click on the Security link.
On the resulting page, select which profiles should have access and click on the Save button.
Opening the following URL in your browser displays a list of accounts: https://<instance>/apex/PopupMain
.
Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.

Note
Note that as this page uses a standard list controller, the list of accounts displayed will be that of the last list view that the user accessed.
The detail link markup is as follows:
<apex:outputLink title="View detail in a popup window" onclick="return openPopup('{!acc.Id}');"> Details </apex:outputLink>
The onclick
attribute defines the JavaScript function to be invoked when the link is clicked; note the {!acc.id}
merge field, which passes the ID of the chosen account to the function.
The JavaScript function uses the window.open
function to open the new window.
var newWin=window.open('{!$Page.Popup}?id=' + id, 'Popup', 'height=600,width=650,left=100,top=100,resizable=no,scrollbars=yes,toolbar=no,status=no');
The final parameter details the features required for the new window as a comma separated list of name=value
pairs.
Clicking on the Details link displays the full account details in a pop-up window.

The Adding a custom lookup to a form recipe in Chapter 3, Capturing Data Using Forms shows how information can be captured in a pop-up window and passed back to the main window to populate input fields.
When a Visualforce page is deployed to production, only users whose profiles have been given access via the security settings will be able to access the page. Any user with a profile that does not have access will receive an Insufficient Privileges error, which is not a good experience and can lead users to think that the page is crashing.
A better solution is to check whether the user has access to the page and if they do not, present a user-friendly message that explains the situation and directs them to where they can get more help.
In this recipe we will create a launch page accessible to all profiles that checks if the user has access to the protected page. If the user has access, they will be transferred to the protected page, while if they don't, they will receive an explanatory message.
This recipe requires a second user login. Ensure that this is not created with the System Administrator profile, as that profile has access to all Visualforce pages regardless of the security settings.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
Protected
in the Label field.Accept the default Protected that is automatically generated for the Name field.
Paste the contents of the
Protected.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the Protected page and click on the Security link.
On the resulting page, ensure that the profile of your second user does not have access to the Protected page.
Log in using your second user credentials and attempt to access any account record. You will receive an error message as shown in the following screenshot:
Next, create the launch page controller by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
LaunchController.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Click on the New button.
Enter
Launch
in the Label field.Accept the default Launch that is automatically generated for the Name field.
Paste the contents of the
Launch.page
file from the code download into the Visualforce Markup area.Click on the Save button to save the page.
Navigate to the Visualforce setup page by clicking on Your Name | Setup | Develop | Pages.
Locate the entry for the Setup page and click on the Security link.
On the resulting page, give access to all of the profiles and click on the Save button.
Log in using your second user credentials and open the following URL in your browser: https://<instance>/apex/Launch
.
Here, <instance>
is the Salesforce instance specific to your organization, for example, na6.salesforce.com.
The resulting page displays a friendly error message detailing that your user does not have access to the page, and renders a clickable link to request access.

The Launch page declaration contains an action
attribute.
<apex:page controller="LaunchController" action="{!allowAccess}">
This invokes the allowAccess
action method in the controller before the page is rendered.
public PageReference allowAccess() { PageReference pr=Page.Protected; try { pr.getContent(); } catch (Exception e) { pr=null; } return pr; }
The allowAccess
method attempts to retrieve the contents of the protected page programmatically. If the contents are retrieved successfully, it returns the page reference for the Protected page, which redirects the user to that page. If an exception occurs, the method returns null
, which leaves the user on the Launch page and displays the friendly error message.
Writing unit tests for Visualforce page controllers is often a source of confusion for developers new to the technology. A common mistake is to assume that the page must somehow be rendered and interacted with in the test context, whereas, in reality the page is very much a side issue. Instead, tests must instantiate the controller and set its internal state as though the user interaction had already taken place, and then execute one or more controller methods and confirm that the state has changed as expected.
In this recipe we will unit test SearchFromURLController
from the Reacting to URL parameters recipe.
This recipe requires that you have already completed the Reacting to URL parameters recipe, as it relies on SearchFromURLController
being present in your Salesforce instance.
Create the unit test class by navigating to the Apex Classes setup page and by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
SearchFromURLControllerTest.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
On the resulting page, click on the Run Tests button.
The tests successfully execute as shown in the following screenshot:

Navigating back to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes shows that the tests have achieved 100 percent coverage of the controller.

Tip
Percentage coverage is important as at least 75 percent coverage across all code must be achieved before classes may be deployed to a production organization.
The test class contains two unit test methods. The first method tests that the search is correctly executed when the search term is passed on the page URL. As unit tests do not have access to organization data, the first task for the test is to set up three test accounts.
List<Account> accs=new List<Account>(); accs.add(new Account(Name='Unit Test')); accs.add(new Account(Name='Unit Test 2')); accs.add(new Account(Name='The Test Account')); insert accs;
As the controller is reacting to parameters on the URL, the page reference must be set up and populated with the name
parameter.
PageReference pr=Page.SearchFromURL; pr.getParameters().put('name', 'Unit'); Test.setCurrentPage(pr);
Finally, the controller is instantiated, which causes the action method that executes the search to be invoked from the constructor. The test method then confirms that the search was executed and the actual number of matches equals the expected number.
SearchFromURLController controller=new SearchFromURLController(); System.assertEquals(true, controller.searched); System.assertEquals(2, controller.accounts.size());
The second unit test method tests that the search is correctly executed when the user enters a search term. In this case, there is no interaction with the information on the page URL, so the test simply instantiates the controller and confirms that no search has been executed by the constructor.
SearchFromURLController controller=new SearchFromURLController(); System.assertEquals(false, controller.searched);
The test then sets the search term, executes the search method, and confirms the results.
controller.name='Unit'; System.assertEquals(null, controller.executeSearch()); System.assertEquals(2, controller.accounts.size());
Controller extensions provide additional functionality for standard or custom controllers. The contract for a controller extension is that it provides a constructor that takes a single argument of the standard or custom controller that it is extending. Testing a controller extension introduces an additional requirement that an instance of the standard or custom controller, with appropriate internal state, is constructed before the controller extension.
In this recipe we will create a controller extension to retrieve the contacts associated with an account managed by a standard controller and unit test the extension.
As the test class makes reference to the controller extension, this must be created first.
Navigate to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
AccountContactsExt.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
Create the unit test class by navigating to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes.
Click on the New button.
Paste the contents of the
AccountContactsExtTest.cls
Apex class from the code download into the Apex Class area.Click on the Save button.
On the resulting page, click on the Run Tests button.
The tests successfully execute as shown in the following screenshot:

Navigating back to the Apex Classes setup page by clicking on Your Name | Setup | Develop | Apex Classes shows that the tests have achieved 100 percent coverage of the controller.

The test class contains one unit test method. As unit tests do not have access to the organization data, the first task for the test is to set up the account and contact information.
Account acc=new Account(Name='Unit Test'); insert acc; List<Contact> contacts=new List<Contact>(); contacts.add(new Contact(FirstName='Unit', LastName='Test', Email='Unit.Test@Unit.Test', AccountId=acc.id)); contacts.add(new Contact(FirstName='Unit', LastName='Test 2', Email='Unit.Test2@Unit.Test', AccountId=acc.id)); insert contacts;
Next, the instance of the standard controller is instantiated.
ApexPages.StandardController std= new ApexPages.StandardController(acc);
Note that the standard controller requires the sObject record that it is managing as a parameter to the constructor. As this is the record that will be made available to the controller extension, it must have the fields populated that the extension relies upon. In this case, the only field used by the extension is the ID of the account, and this is automatically populated when the account is inserted.
Tip
In this recipe the records to be tested are created in the test classes. In the real world, this is likely to lead to a lot of repetition and a maintenance overhead. In that case, a utility class to handle the set up of test data would be a more robust solution.
Finally, the controller extension is instantiated, taking the standard controller as a constructor parameter, and the test verifies that the extension has successfully retrieved the associated contacts.
AccountContactsExt controller=new AccountContactsExt(std); System.assertEquals(2, controller.contacts.size());