Given a custom controller that uses a record selected by a standard controller (not through id parameter), how can I ensure that the appropriate Custom_Field__c field is available in the unit test?

On the page, I add the hidden input field so that Salesforce picks up the backing field:

<apex:inputHidden value="{!Custom_Object__c .Custom_Field__c }"/>

Then, in the controller, I rely on the existence of the field to verify if the record is ok:

public with sharing class CustomController {

    private Custom_Object__c obj;

    public CustomController (ApexPages.StandardController stdCtrl) {
        this.obj = (Custom_Object__c )stdCtrl.getRecord();

        // selected due to <apex:inputHidden value="{!Custom_Object__c .Custom_Field__c }"/>
        if (obj.Custom_Field__c == false) {
             throw new CustomException('Error message.');   

If I test with something like this:

    Test.setCurrentPage(new PageReference('/apex/CustomPage?id=' + obj.Id));

    ApexPages.StandardController stdCtrl = new ApexPages.StandardController(obj);
    CustomController ctrl = new CustomController (stdCtrl);

then a CustomException gets thrown because the field Custom_Field__c is not available to the controller.

I know that I could capture the ID through the parameter and then select the record

 Id recordId = ApexPages.currentPage().getParameters().get('id');
 this.obj = [select Id, Custom_Field__c from Custom_Object__c where Id = :recordId];

However, I'd like to keep the default record Id checking from Salesforce (so that one cannot manually input an Id of a record with a wrong object type). I'm also aware that this can be prevented with something like:

Id recordId = ApexPages.currentPage().getParameters().get('id');
if (recordId.getSObjectType() != Custom_Object__c.sObjectType) {
    throw new CustomException('Wrong object type.');    

Still, I'm interested in the original question.


When you are providing an object to the standard controller, you are responsible for selecting the appropriate record and its fields instead of the standard controller. In a test, that would look like this:

Custom_Object__c obj = [Select Custom_Field__c from Custom_Object__c where Id = :someId limit 1];
ApexPages.StandardController stdCtrl = new ApexPages.StandardController(obj);

or even:

Custom_Object__c obj = new Custom_Object__c(Custom_Field__c = true); // or = false
ApexPages.StandardController stdCtrl = new ApexPages.StandardController(obj);

(if the record doesn't need to be in the database). This standard controller can then be passed to a custom controller:

CustomController ctrl = new CustomController (stdCtrl);

So a workaround is to provide the correct record (with the required fields selected) yourself.

  • ipavlic - please mark this an answer – cropredy May 12 '15 at 23:01

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.