Saturday, November 24, 2007

Even More ColdSpring Updates!!

Ok, this is something my coworker Cliff Meyers has been trying to get me to write for ages. We use the Spring equivalent of this literally every day. Now, unit testing ColdSpring managed beans is not really all that hard, all you need to do is create a bean factory, load your config file, and call getBean() for anything you want to test. But you know what? That's too much work! Enter AbstractAutowireTests, which you will find in the new coldspring.cfcunit package (yes, I do intend to make more!). Here's how it works, extend this class instead of Paul's TestCase, override the getConfigLocations function, and that's it, everything else is handled for you! Oh yeah, this is an Autowired test case too, so just add setters for whatever bean you want to write tests against, VERY handy. Here's an example of a test case using this new component:



<cfcomponent extends="coldspring.cfcunit.AbstractAutowireTests">

    <cffunction name="getConfigLocations" access="public" returntype="string" output="false">
        <cfset var path = GetDirectoryFromPath(getMetaData(this).path) />
        <cfreturn path & "/testBeans.xml" />
    </cffunction>

    <cffunction name="onSetUp" access="public" returntype="void" output="false">
        <!--- this is where my setup would be... --->
        <cfset variables.sys = CreateObject('java','java.lang.System') />
        <cfset variables.sys.out.println("onSetUp executed!") />
    </cffunction>

    <cffunction name="onTearDown" access="public" returntype="void" output="false">
        <!--- this is where my teardown would be... --->
        <cfset variables.sys.out.println("onTearDown executed!") />
    </cffunction>

    <cffunction name="setStructBean" access="public" returntype="void" output="false">
        <cfargument name="structBean" type="coldspring.tests.structBean" required="true" />
        <cfset variables.structBean = arguments.structBean />
    </cffunction>

    <cffunction name="testNothing" access="public" returntype="void" output="false">
        <cfset variables.sys.out.println("some structBean data: " & variables.structBean.getData().intOne) />
        <cfset AssertNotNull(variables.structBean) />
    </cffunction>

</cfcomponent>


A few things to point out here. Right now setConfigLocations is not 100%, it only works with 1 config file, but I will have that done any time now. Also, paths are difficult with cfcUnit as far as location of your config file. Using GetDirectoryFromPath(getMetaData(this).path) ensures that I can refer to a path relative to the cfc being tested. And finally, I am using setUp and tearDown, which are called by cfcUnit's test runner to preform my own set up and tear down actions, so instead you should use onSetUp and onTearDown, which will be properly called by the AbstractAutowireTests. For me, this has been an incredible time saver at work, so I hope you enjoy and find this useful! Now if Paul Kenney answers my email I have even more to commit. Cough, cough...

1 Comments:

Blogger Dom said...

Hi Chris, great work :)

I have a test case up and running; my getConfigLocations() method sets the configPath explicitly and my onSetup() loads the bean for my test case using 'variables.myBean = beanFactory.GetBean('someBean')'. My tests can now access the bean which is great.

What I am unsure about is the meaning and use of the setStructBean() method in your example. Am I missing some extra goodiness? Could you possibly expand?

Dominic

6:07 AM  

Post a Comment

<< Home