Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
Diagram illustrating the process of writing an Apex test class for a standard Salesforce controller
Apex

Test Class for Standard Controller

The short answer

Visualforce pages using only standard controllers do not require test classes, but any accompanying Apex controller extension must be tested for deployment. The example below tests an extension class by instantiating ApexPages.StandardController and setting the Visualforce page context.

Key takeaways Write unit test classes for Apex controller extensions to satisfy deployment requirements, even though standalone standard controllers do not need them. Instantiate ApexPages.StandardController in your test method by passing an inserted sObject record into its constructor. Pass the ApexPages.StandardController instance into the constructor of your custom extension class. Set the Visualforce page context and record URL parameters using PageReference and Test.setCurrentPage() before calling extension methods.

Test classes are needed in order to deploy the functionality in production. Visualforce pages having standard controller do not require any test class to be written. However when you need to deploy the pages with standard controller along with apex extension, test class needs to be implemented for extension controller.

Lets say we have visualforce page to show account along with extension to query all contacts of account where contact status is 'Active'

Visualforce Page:

<Apex:page standardController="Account" extensions="AccountActiveContactsController">
    <apex:pageBlock title="{!Account.Name}">
        <apex:pageBlockSection >
            <Apex:outputField value="{!Account.AccountNumber}"/>
            <Apex:outputField value="{!Account.Type}"/>
            <Apex:outputField value="{!Account.Phone}"/>
            <Apex:outputField value="{!Account.Website}"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
    <apex:pageBlock title="Contacts">
        <apex:pageBlockTable value="{!Contacts}" var="Con">
            <apex:column value="{!Con.FirstName}"/>
            <apex:column value="{!Con.LastName}"/>
            <apex:column value="{!Con.Email}"/>
            <apex:column value="{!Con.Phone}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

Apex Extension

public with sharing class AccountActiveContactsController {
    Account A;
    public AccountActiveContactsController(ApexPages.StandardController controller) {
        A = (Account)controller.getRecord();
    }
    
    public list<contact> getContacts(){
        return [select id, FirstName,LastName, Email, Phone from Contact where Status__c = 'Active'  and AccountId =: A.id];
    }
}
  • Visualforce page is implemented using "Account" as Standard controller.
  • Using apex extension, we are querying contacts which are having Status (Custom Field) as Active

Output as follows:

Test Class for Standard Controller

Show Active Contacts of Account

Now to write the test class, we need to let compiler know that's its extending logic of standard controller of one of the visualforce page. We can do this following way:

@isTest
public class TestAccountActiveContactsController {
    static testMethod void CoverClass(){
        Account A = new Account(name = 'Test');
        insert A;
        System.assert(A.id != null);
        
        List<Contact> Contacts = new List<Contact>();
        Contacts.add(new Contact(FirstName = 'test1', LastName = 'test1', Email = '[email protected]', Status__c = 'Active'));
        Contacts.add(new Contact(FirstName = 'test2', LastName = 'test2', Email = '[email protected]', Status__c = 'Active'));
        Contacts.add(new Contact(FirstName = 'test3', LastName = 'test3', Email = '[email protected]', Status__c = 'Active'));
        Contacts.add(new Contact(FirstName = 'test4', LastName = 'test4', Email = '[email protected]', Status__c = 'Active'));
        Contacts.add(new Contact(FirstName = 'test5', LastName = 'test5', Email = '[email protected]', Status__c = 'Inactive'));
        insert Contacts;
        
        Test.startTest();
        ApexPages.StandardController sc = new ApexPages.StandardController(A);
        AccountActiveContactsController AACC = new AccountActiveContactsController(sc);
        
        PageReference pageRef = Page.AccountActiveContacts;
        pageRef.getParameters().put('id', A.Id);
        Test.setCurrentPage(pageRef);

        AACC.getContacts();
        Test.startTest();
    }
}
  • ApexPages.StandardController sc = new ApexPages.StandardController(A)
    • Instantiate standard controller and passed the sObject instance on which the standard controller is written. Here the visualforce page is written on Account object. We are passing account instance in constructor of ApexPages.StandardController.
  • AccountActiveContactsController AACC = new AccountActiveContactsController(sc)
    • Instantiate apex extension and pass standard controller instance in constructor.
  • PageReference pageRef = Page.AccountActiveContacts
    • Instantiate PageReference with the visualforce page on which extension is linked.
  • pageRef.getParameters().put('id', A.Id)
    • Passing account id through URL so that it will get captured in extension apex.
  • AACC.getContacts();
    • Call any function with the help of extension instance.

Frequently asked questions

Do Visualforce pages with standard controllers require a test class?

Visualforce pages that rely solely on standard controllers do not require test classes for deployment. However, if a page uses an Apex controller extension, you must write a test class to cover the extension code.

How do you instantiate a StandardController in an Apex test class?

Create and insert your test sObject record, then pass that record instance into the constructor using ApexPages.StandardController sc = new ApexPages.StandardController(recordInstance).

How do you test an Apex controller extension for a Visualforce page?

Instantiate ApexPages.StandardController with your test record, pass that controller instance into the extension's constructor, set the page context with Test.setCurrentPage(), and invoke the extension's methods.

Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment