Hi Ken,
Welcome! I hope others will chime in, too ...
You're right on target with unit testing and with respect to dealing
with databases. The issue is that databases are volatile and can make
your tests fragile if the database changes. You have a couple of
options: (1) you can have a database sandbox where you have control
over its state and maintain that state in setUp() and tearDown() or
with some other private methods; or (2), and this is my preferred
method, is to mock those things that touch the "outside world". In
other words, you can spoof any method that depends upon a database and
thereby bypass the database altogether. This will allow you to test
your code without having to depend on database connections or state.
You can accomplish this using Brian Kotek's ColdMock, Mike Steale's
CFEasyMock, or MXUnit's built-in injectMethod(...) -
http://mxunit.org/doc/index.cfm?doc=injectmethod.
So, if it were me, I would do something like this:
<cffunction name="testRetrievePage">
<cfscript>
var expected = 'myId';
var actual = '';
var mgr = createObject("component","PagesManager");
//Ok. Now anytime we call retrievePage() we're calling _retrievePage
() instead. Nice, Marc!
injectMethod(this, mgr, "_retrievePage", "retrievePage");
actual = mgr.retrievePage().id;
assertEquals(expected, actual);
</cfscript>
</cffunction>
<!--- Mock method : note PRIVATE access --->
<cffunction name="_retrievePage" access="private" returnType="query">
//...preferably use QuerySim, WDDX or
var q = queryNew('id,col2,...');
queryAddRow(q);
querySetCell(q, 'id' , 'myId');
etc ...
<cfreturn q />
</cffunction>
The above tests your code without hitting the db. You would do the
same thing with createPage() - mock it. With that said, you will, at
some point, want tests that also hit the db.
bill