1

Assuming I have two picklists in my VF page, something like this:

<apex:selectList value="{!parentId}" id="cmbParent" size="1" required="true" label="Parent">
  <apex:selectOptions value="{!parents}" />
  <apex:actionSupport event="onchange" action="{!clearChild}" reRender="cmbChild"/>
</apex:selectList>
<apex:selectList value="{!childId}" id="cmdChild" size="1" label="Child">
  <apex:selectOptions value="{!children}" />
</apex:selectList>

In a nutshell, if someone changes the value of the parent picklist, that should call the action method clearChild() and then re-render the child picklist.

I would like to know, in the test class, even if I have called the Test.setCurrentPage, if I programmatically change the parentId, is that not supposed to call the action method automatically?

i.e.

TestCase__c  testcase = new TestCase();
Test.setCurrentPage(Page.MyTestPage);

ApexPages.standardController std = new ApexPages.standardController(testcase);
MyTestCaseExt controllerExt = new MyTestCaseExt(std);

controllerExt.parentId.value = 3;

// after the above line, can I count on the action method clearChild getting called?
// Or do I need to call it explicitly?
//controllerExt.clearChild();
System.assertEquals(null, controllerExt.childId);

I'm asking because it seems to me the action method does not actually get called even though I have specifically set the page reference.

Originally I thought when the parent picklist value changes, it will automatically call the action method to clear the content of the child picklist. If I have to call the action method myself, then obviously my assert will be successful. It'll be like, I set variable a to 3, and then I check if a equals 3, which is kind of pointless, is it not?

Thanks King

1 Answer 1

3

The test environment really only handles Apex code. AFAIK the only value of Test.setCurrentPage is to fake the return value of ApexPages.currentPage() that an Apex controller might rely on. The Visualforce page is not executed to produce HTML and there is no emulation of a browser and its DOM events such as "onchange".

So your Apex test code has to take the place of the Visualforce and directly call the methods and reference the properties. That makes it possible to check that the Apex does what you expect it to to. If your Visualforce is doing relatively little, then that is probably enough. And the Visualforce can be manually tested...

But if you want to automate the testing of how the overall combination of Visualforce (and perhaps jQuery) and the Apex controller work together, then you will have to build UI-level tests too and Selenium is the commonly chosen platform to use for that. But it is quite a lot of work and such tests tend to be fragile unless carefully written, where a small change in a page can break lots of tests.

2
  • Hi Keith - thanks a lot. Yeah I was really quite disappointed as I thought if I make a change to the parent controller, then all the action methods would be called automatically and then I could just check to see if the final result is correct. Now, because I have to call every single method, then it is really going to be like, "I'm going to set variable a to 3", and then "Is a equal 3"? I thought that is really quite silly that way.
    – kingkoo
    Mar 31, 2014 at 1:29
  • @kingkoo Many (including me) would argue that you should only test things that can break which means less than 100% code coverage is normal. My code typically has about 90% code coverage on average, with controllers having less and classes that implement algorithms having more.
    – Keith C
    Mar 31, 2014 at 7:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .