Even if available, I wouldn't recommend testing against the results of .toHtml()
- if you've ever looked at the html output of a VF page, you know that there is lots of extra bits added by the system - ids, classes, event handlers - that aren't guaranteed to not change. You are much better off inspecting and asserting against the object returned.
nowhere can I find a list of methods for what I can do with an ApexPages.Component object
The list is available, but it isn't very helpful. In particular, .expressions
(and .facets
, I would guess, although I did not test it) appears to be write-only. This leaves us with .childComponents
, but that's enough to traverse the tree of VF objects returned. So how to ensure that the results are correct?
I'd point out as a side note here that the degree to which you need to test depends on the amount of logic in your dynamic code. For example, in the sample code in @[Mohith Kumar]'s answer (and which my sample code, below, is based on) really only has one thing that needs to be tested - the conditional. Confirming that the method does or doesn't return a component is enough - the rest of the code that builds the pageBlock is basic VF; you should be testing your application logic, not the services provided by the platform.
That said, there will of course be more complex code where many parts of the dynamic response may depend on the inputs, and so it may be necessary to assert much of the response. There are three tools we can use to do so:
- We can use
.childComponents()
to traverse the tree of VF components returned.
- We can use the instanceOf operator to confirm that the VF components in the tree are of the expected type, allowing us to confirm (for example) that we got a grid instead of a table.
- We can cast any
ApexPages.Component
to it's actual type, allowing us to access all of the properties of the object.
Here's a simple demo controller, based on the sample code in Mohith's answer:
public class DynTestPageController{
public Component.Apex.pageBlock getStartpage(){
if(true){ //this would be a real conditional in real code.
Component.Apex.pageBlock pg=new Component.Apex.pageBlock(id='PanelId', title='Main Block');//formation of pageblock
Component.Apex.panelGrid pgrid=new Component.Apex.panelGrid(id='GridId');//formation of panelGrid
pgrid.columns=3;
Component.Apex.outputText outtx1=new Component.Apex.outputText();
outtxt1.value='Welcome to the start page';
Component.Apex.outputText outtxt2=new Component.Apex.outputText();
outtxt2.value='';
Component.Apex.CommandButton startbutton=new Component.Apex.CommandButton();
startbutton.Value='Begin';
startbutton.expressions.action='{!save}';
pg.childComponents.add(pgrid);
pgrid.childComponents.add(outtxt1);
pgrid.childComponents.add(outtxt2);
pgrid.childComponents.add(startbutton);
return pg;
}else {
return null;
}
}
}
And here's a test class to validate the dynamic VF generated:
@isTest
public class DynTestPageControllerTest{
@isTest
public static void testStartpage() {
DynTestPageController controller = new DynTestPageController();
Component.Apex.pageBlock pblk=controller.getstartpage();
system.assertNotEquals(null, pblk); //did we get a component?
system.assertEquals(pblk.title, 'Main Block'); //assert component property
system.assertEquals(1, pblk.childComponents.size()); //do we have correct # of children
//first (and only) child
system.assert(pblk.childComponents[0] instanceOf Component.apex.panelgrid); // correct type?
Component.apex.panelgrid pgrid = (Component.apex.panelgrid)pblk.childComponents[0]; // cast it to access props
system.assertEquals(3, pgrid.columns); //assert child component property
system.assertEquals(3, pgrid.childComponents.size()); // continuing down the tree...
//first child of panelgrid
system.assert(pgrid.childComponents[0] instanceOf Component.apex.outputtext);
Component.apex.outputText ot = (Component.apex.outputText)pgrid.childComponents[0];
system.assertEquals('Welcome to the start page', ot.value);
//second child of panelgrid
system.assert(pgrid.childComponents[1] instanceOf Component.apex.outputtext)
ot = (Component.apex.outputText)pgrid.childComponents[1];
system.assertEquals('', ot.value);
//third child of panelgrid
system.assert(pgrid.childComponents[2] instanceOf Component.apex.commandbutton);
Component.apex.commandButton btn = (Component.apex.commandButton)pgrid.childComponents[2];
system.assertEquals('Begin', btn.value);
system.assertEquals('#{save}', btn.action.getExpression());
}
}
Of course, you may need a little experimentation and cave-man debugging (a.k.a., System.Debug() calls) to determine the correct way to test some things. For example, see the last assert above - Originally, I was asserting for '{!save}'
, but apparently it is internally stored as '#{save}'
.
Updated 8 Sep 2013 to use instanceOf for type checking instead of toString. Thanks to @[Andrew Fawcett] for the suggestion.
Unit tests are meant to exercise your code so that you can test what you would expect to happen in your code. When I'm writing unit tests, I go back to the functional requirements of my code and think about what logic it performs. How would I setup all of the context and data for my code to execute in the way I was expecting?
In your case, you are returning a list of events. As such, your unit test needs to create those events so they can be returned. The reason that you have big blocks of code not being exercised is because you aren't getting into the for loop of your test because there are no events in the database in the unit test context (isolated from the data in your instance). Create an event, which you'll need to hardcode to the specific owner you listed in your controller prior to all of the code that's currently in your test.
Here is a good article about best practices for writing unit tests:
https://developer.salesforce.com/page/How_to_Write_Good_Unit_Tests
Best Answer
I'm assuming your flow is an interactive flow? If so, you can't test it.
If it is a trigger-ready flow, then you need to use the start() method to trigger the flow.