Testing Visualforce Custom Controller

Custom Controller

Testing Visualforce custom controller is required because custom controllers like all Apex codes, should be covered by unit tests. A custom controller is an Apex class that implements all of the logic for a page without leveraging a standard controller.

Custom controllers contain custom logic and data manipulation that can be used by a Visualforce page. Use custom controllers when you want your Visualforce page to run in system mode, which does not enforce the permissions and field-level security of the current user. For example, a custom controller can retrieve a list of items to be displayed, make a callout to an external web service, validate and insert data, and so on.

Testing

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 @isTest annotation in the method definition.

For this post,consider the custom controller – updateRecordCon

public class updateRecordCon {

  public List<Bank__c> banks {get;set;} 
  public updateRecordCon (){
      init(); 
    }
   public void init() {   
      banks = [select Id, Name, Works__c, Region__c, Source__c, Services__c 
     from Bank__c ORDER BY Name LIMIT 4];   
   } 
   
    public PageReference updateRecord(){             
        update banks;
     
        init();
        return null;
    }   
}

The Visualforce markup named updateListRecords below uses the controller above:

<apex:page controller="updateRecordCon">
 <style type="text/css">
  #title {
  font-size: 150%;
  margin-left: 30%;
  }
 </style>
  
  <h2 id="title">Update Banks Records</h2><br/><br/>
    <apex:form >
    <apex:pageBlock >
        <apex:pageBlockTable value="{!banks}" var="b">
            <apex:column headervalue="Bank Name">
                <apex:OutputText value="{!b.Name}" /> 
            </apex:column>            
            <apex:column headervalue="Source">
                <apex:OutputText value="{!b.Source__c}" />
            </apex:column>
            <apex:column headervalue="Services">
                <apex:inputText value="{!b.Services__c}" />
            </apex:column>
            <apex:column headervalue="Region">
                <apex:inputText value="{!b.Region__c}" />
            </apex:column>            
           <apex:column >
                <apex:commandLink action="{!updateRecord}" value="Update"/>                            
            </apex:column>                                                                                             
    </apex:pageBlockTable>   
    </apex:pageBlock>
    </apex:form>   
        
</apex:page>

The Apex Test class below test the controller – updateRecordCon

@isTest
public class updateRecordCon_Test {
    //Each of the two test methods here gives a 83 test coverage
 @isTest static void testUpdateRecords(){
      
      Bank__c b = new Bank__c(Name= 'CitiyBank', Source__c='Web',  
       Works__c='Gen Repairs', Region__c='West', Services__c='Repairs');
       insert b;
       
     Test.StartTest();
 
     PageReference pageRef = Page.updateListRecords;
        Test.setCurrentPage(pageRef);
        
        ApexPages.currentPage().getParameters().put('id', String.valueOf(b.Id));
      
     updateRecordCon controller = new updateRecordCon();
       controller.updateRecord();
 
       controller.init();    
    PageReference prf = controller.updateRecord();
     System.assertEquals(null, prf); //assertion
        Test.StopTest();
    }
}

Running the test gave 100% test coverage. Click the Test tab to check the status of the TestRun. Expand it to see the test class and the method result like the image below:

UpdateTestRun

Check my post on Testing Visualforce Controller Extension if you want to know how test this type of Apex script

Resources
Trailhead
Visualforce Developer Guide