How does one test Visualforce components with custom controllers

I have created a custom Visualforce component.

It is backed by a custom controller.

I am struggling to write unit tests for it.

The limited VisualForce documentation indicates that to test it I should:

  1. put the component in a page eg <apex:page standardController='Lead'><c:Component></c:Component></apex:page>
  2. call Test.setCurrentPage(Page.TestPage)
  3. Set Page parameters `ApexPages.currentPage().getParameters().put(‘Id’, lead.Id);
  4. Instantiate an instance of the controller for the component ComponentController cont = new ComponentController()

And then I should be able to use the controller as though it backed the VF component as included in that page.

But for whatever reason, when I do that in a test, the ComponentController does not reflect the state it should have if it was being used in that page. It seems a bit magical to assume it would work this way, and there is no documentation indicating that it should or should not, so I am pretty confused as to what to do.

For Reference, my actual code looks like this.

<apex:page standardController="Lead" showHeader="false" >
    <c:CustomComponent record="Lead" />
</apex:page>

<apex:component controller="CustomComponentController" allowDML="true">
    <apex:attribute 
        name="record"
        description="Which Record type"
        type="Object"
        required="true"
        assignTo="{!sObj}" />
    {!recType}
</apex:component>

public class CustomComponentController {
    public Object sObj {get; set;}

    public String getRecType() {
        return (String)sObj;
    }
}

@isTest
public class TestCustomComponentController {
    public static testmethod void doTest () {
        Test.setCurrentPage(Page.ThePage);
        CustomComponentController cont = new CustomComponentController();
        System.assertEquals(cont.getRecType(), 'Lead');
    }
}

Implemented like that, input into a page I can see that {!recType} evaluates to lead, but when I run the test getRecType() returns null.

I would really like a reference to how all of these things are architected, because I am sure to come across other issues like this in the future, but I can’t find anything except simple examples.

Answer

Testing a controller is independent of testing the component. That is, you test the controller by simulating the inputs to the controller’s properties as if VF passed them to the controller . Thus, your testmethods need to set the controller properties.

So, your testmethod should look like

@isTest
public class TestCustomComponentController {
    public static testmethod void doTest () {
        Test.setCurrentPage(Page.ThePage);  // not really needed to test the component itself
        CustomComponentController cont = new CustomComponentController();
        cont.sObj = new Lead();   // simulate the assignTo operation on the apex:attribute
        System.assertEquals(cont.getRecType(), 'Lead');
    }
}

You don’t need to put the component on a testpage to test the controller

BTW — I’m a bit confused by the method getRecType() – it is returning the sObj as a string. SFDC recordTypes are a concept altogether different from sObjects so you might want to change your methodname

Attribution
Source : Link , Question Author : Alex H , Answer Author : cropredy

Leave a Comment