comment

Java For Mac OS X 10.5 Update 2 - ColdFusion 8 Gotcha

2008 October 28
No Comments
If you're a Mac person and haven't already installed ColdFusion 8 on 10.5 (Leopard), be aware that updating Java will cause the ColdFusion 8 (64-bit OS X) installer to fail. The problem appears to be that the Java version "1.5.0_16" is unrecognized by the installer as a supported 64-bit version of Java. Note that CF8 will run on Java version 1.5.0_16 for Mac, but it will not install to it.

ColdSpring Reloaded

2008 September 12
No Comments
Coldspring was the first Coldfusion-based "framework" that I integrated into my application development process. I can't claim to be an expert, but today I'll step up and try evangelism. Based on the popular Java Spring framework, Coldspring provides a solid foundation for applications with features like dependecy injection, aspect-oriented programing, remote proxy generation and more. If you already use ColdSpring, or want to learn how to use it, I highly recommend the new Quickstart Guide and Examples written by ColdSpring guru Brian Kotek. In addition to a new look and documentation update, version 1.2 is now final! Get ye to the Springery...

For the Love of Chocolate, Style Your Optgroup!

2008 September 10
No Comments
If you haven't tried out the cfUniForm tag library by Matt Quackenbush, I highly recommend it. Version 2.3 includes some nice updates proposed by Bob Silverberg, including the addition of optgroup to select lists. I don't like the default italic style for an optgroup label, so when I use it, I add a simple css selector to make them a little more visually appealing. For example: optgroup {
   font-weight: bold;
   font-style:normal;
}
Don't let default optgroup styles drag you down. Make them great with a little CSS.

My Approach to Test Driven Development Part 3 - Testing Against a Database

2008 September 08
No Comments
Confidently unit testing code that relies on a database is troublesome. There are many different approaches and many opinions on the matter. I've previously written about using transactions to safely rollback the database after every test. This worked well for me at the time, but there are pitfalls in using that approach. Recently, I've done some more research on the subject and even attempted, without success, to integrate DBUnit into my database reliant unit tests. After some trial and error, I landed on the following approach that is a culmination of a few ideas I'd previously heard of, but never tried. The goal of this approach is to:
  1. Run tests against a known data set.
  2. Reset the entire database prior to each test.
The example code that follows requires a test database, test database user and a test datasource targeting the test database.

read more...

My Approach to Test Driven Development Part 2 - MXUnit, Coldspring and ColdMock

2008 August 28
No Comments
Like the title says, this post will include code samples for setting up an MXUnit test case using ColdSpring and ColdMock. The goal of any test case are to isolate the component under test as much as possible. I find ColdMock to be a simple and powerful tool for achieving test isolation. For this example, I created a test case for my ConfigFactory which I mentioned in a previous post. TheConfigFactory component has a constructor dependency on the Environment Config component developed by Rolando Lopez which makes this a good case for mocking. Here's a snapshot of the files used in this sample test setup, A common convention for test cases is to add the suffix "Test" to match the test case to the component being tested. I have my own convention for setting up tests withColdSpring bean definitions which I keep in a similarly named xml file. All test cases extend the BaseTestCase which contains a couple of methods to simplify test configuration with ColdSpring. The full code of the of the BaseTestCase follows. <cfcomponent displayname="tests.BaseTestCase" extends="mxunit.framework.TestCase" output="false">

<cfset variables.beansXML = "">

<cffunction name="setBeanFactory" access="private" output="false" returntype="void">
<cfargument name="beansXML" type="string" required="true">
<cfargument name="params" type="struct" required="false" default="#structnew()#">
<cfscript>

if ((not structkeyExists(request,"beanFactory")) or (comparenocase(variables.beansXML,arguments.beansXML) neq 0))
{
variables.beansXML = arguments.beansXML;
request.beanFactory = createObject("component" ,"coldspring.beans.DefaultXmlBeanFactory").init(StructNew(),arguments.params);
request.beanFactory.loadBeans(variables.beansXML);
}
</cfscript>
</cffunction>

<cffunction name="getBeanFactory" access="private" output="false" returntype="any">
<cfreturn request.beanFactory>
</cffunction>

</cfcomponent>
In the past I kept my ColdSpring reference in variables scope, but I found that when testing components based that rely on Transfer ORM, I can shave the time of tests considerably when I have multiple tests in the same test case. Whether you run the MXUnit HttpAntRunner, the eclipse plugin or a manually configured test suite within a browser they all run as a single request, so as you define more tests it helps to speed things up. Here's what the ConfigFactoryTest.xml looks like. <beans>
<bean id="mockFactory" class="tests.MockFactory" singleton="true" />

<bean id="EnvironmentConfig" factory-bean="MockFactory" factory-method="createMock">
<constructor-arg name="objectToMock">
<value>model.Environment</value>
</constructor-arg>
</bean>

<bean id="ConfigFactory" class="model.ConfigFactory">
<constructor-arg name="hostName">
<value>${hostName}</value>
</constructor-arg>
<constructor-arg name="environmentConfig">
<ref bean="EnvironmentConfig" />
</constructor-arg>
</bean>

</beans>
You can see how easy it is to mock the dependency using the ColdMock MockFactory. Below is the full code for my ConfigFacotry test case. The important thing to note is that the component display name is used to resolve the path to the ColdSpring bean definitions used in the test suite. <cfcomponent displayname="tests.ConfigFactoryTest" extends="tests.BaseTestCase">

<cffunction name="setUp" access="public" returntype="void">
<cfset var beanDefFileLocation = expandPath('/' & Replace(GetMetadata(this).displayname,'.','/','all') & '.xml')>
<cfset var params = Structnew()>
<cfset params.hostName = "www.somedomain.com">
<cfset setBeanFactory(beanDefFileLocation,params)>
</cffunction>

<!--- Begin Specific Test Cases --->

<cffunction name="testGetSetting" access="public" returntype="void">
<cfscript>
var configFactory = "";
var env = getBeanFactory().getBean("EnvironmentConfig");
var settings = structNew();
settings["MyString"] = "my string";
env.mockMethod('getEnvironmentByUrl').returns(settings);
configFactory = getBeanFactory().getBean("ConfigFactory");
assertTrue(configFactory.getSetting("MyString") eq settings["MyString"]);
</cfscript>
</cffunction>

<cffunction name="testGetAllSettings" access="public" returntype="void">
<cfscript>
var configFactory = "";
var env = getBeanFactory().getBean("EnvironmentConfig");
var settings = structNew();
settings["MyString"] = "my string";
env.mockMethod('getEnvironmentByUrl').returns(settings);
configFactory = getBeanFactory().getBean("ConfigFactory");
assertTrue(StructCount(configFactory.getAllSettings()) eq 1);
</cfscript>
</cffunction>

<cffunction name="testOnMissingMethod" access="public" returntype="void">
<cfscript>
var configFactory = "";
var env = getBeanFactory().getBean("EnvironmentConfig");
var settings = structNew();
settings["MyString"] = "my string";
env.mockMethod('getEnvironmentByUrl').returns(settings);
configFactory = getBeanFactory().getBean("ConfigFactory");
assertTrue(configFactory.getMyString() eq settings["MyString"]);
</cfscript>
</cffunction>

<!--- End Specific Test Cases --->

</cfcomponent>
Most of my tests aren't this involved. Since my ConfigFactory has a constructor dependency on EnvironmentConfig, I pull it out of ColdSpring first, mock the getEnvironmentByUrl method to return a known structure before requesting the ConfigFactory. Truly powerful stuff! I have attached a zip file of this sample test bed as an enclosure for folks to try out.

My Approach to Test Driven Development Part 1 - Application Structure and Apache

2008 August 27
No Comments
As I delve deeper into Test Driven Development (TDD), I have refined my development setup in order to feel confident that my tests are relevant and that they provide immediate feedback about the status of my working code. The two most important goals that I have tried to accomplish with my revisions are to follow the credo of never committing broken code and to isolate and reset the database to ensure the integrity of test data. The following examples are not solely related to TDD, but represent an accumulation of development "best practices" gathered from many sources. I'm going to admit straight up that I am not a TDD purist. I almost always write model components before tests. But I always test before running code on the client side. One of the biggest selling points about unit testing and for me is that I can debug faster should a problem arise and I can do it repeatedly and confidently. Working this way makes me feel somewhat pragmatic. I'm willing to spend a known amount of time setting up and running tests so that I can avoid spending an unknown amount of time debugging. First up, my application directory structure and Apache virtual host settings.

read more...

School's Out...Forever!

2008 August 20
No Comments
Today, I wrote the final exam for the final course I need for my BComm. It was fitting that I wrote it at my home town University in Windsor, Ontario. I live in BC now, but circumstance brought me to Windsor this week, so I made arrangements to write my exam in town. Before the exam, I had that "full circle" feeling walking around the campus I had not set foot on for nearly 20 years. For a little history, I started university in September 1985 and left school in February 1989 to pursue personal interests (of the rock and roll variety). After many joe jobs and many bands, I made the decision to return to school in 1998 as a distance education student. Now ten years later, I've completed the requisites for my degree. It's been a long strange trip and now that it's over I just have to crank up the Alice Cooper...

Dynamic Configuration with Environment Config And a Coldspring Config Factory

2008 June 16
No Comments
When developing web application, it is very likely that at some point you will need to create dynamic configuration for your application in terms of development, staging and production environments. I recently discovered the excellent Environment Config project by Rolando Lopez. Rolando has created a very interesting package with lots of robust features for configuring your application dynamically. There are portions of the package that I must admit, I'm not using (yet). What follows is my current setup for integrating the environment config with a custom factory.

read more...

Model Glue Event Security Using Broadcasts and Results

2008 June 05
No Comments
When building web applications, you will inevitably need to provide secure pages or an entire area of your application for users and administrators. For my most recent Model Glue project I wanted to define a common approach to securing all access to the admin area with the exception of login pages. After several failed attempts at universal security, I decided that securing events is best achieved through explicit broadcasts and results, with a minimal amount of logic handled within the controller. Here's a simple example. Let's presume that the default event for my admin sub-application is "admin.home", here is my event listener declaration. <event-handler name="admin.home">
<broadcasts>
<message name="loginRequired" />
</broadcasts>
<results>
<result name="noValidLogin" do="login.go" redirect="true" />
<result do="layout" />
</results>
<views>
<include name="content" template="home.cfm" />
</views>
</event-handler>
The loginRequired has a listener defined by the following. <controller name="SecurityController" type="admin.controller.SecurityController">
<message-listener message="loginRequired" function="verifyLogin" />
</controller>
Finally, in my SecurityController, the verifyLogin method looks like this. <cffunction name="verifyLogin" access="public" returnType="void" output="false">
<cfargument name="event" type="any">
<cfif not getSecurityService().adminLoggedIn()>
<cfset arguments.event.addresult("noValidLogin")>
</cfif>
</cffunction>
In a previous application I chose to use event.forward() within my controller to redirect the request to the login event. Although this works, it is, in my opinion, better to use addResult and have Model Glue handle the redirection. Although the xml is more verbose, I really like that the intent of each event is clearly defined. Which provides a nice roadmap for any other developers that may take over the project.

Transfer ORM Event Model Examples - BeforeCreate and BeforeUpdate

2008 May 21
No Comments
The topic of how one might track created and modified dates came up on the transfer list today and Brian Kotek mentioned how he uses the transfer event model to track changes when creating or updating Transfer objects. I thought it might be interesting to see just how easy it would be to implement his approach. The transfer event model is an implementation of the Observer/Observable pattern in which one object registers itself to listen for events from another object. When an event occurs on the observable object, the observer (a.k.a listener, or subscriber) is notified. The transfer event model currently supports seven events, each of which require the observer to implement a specific "listener" method. Here's how I decided to implement Brian's approach.

CAVEAT LECTOR I rushed this post out without thinking through the implementation. This is an incorrect and possibly dangerous way to use the transfer event model. Please see Bob Silverberg's post on this topic.

I define a configure() method within all of my transfer decorators. Configure() is invoked when a transfer object is instantiated. This makes it a perfect candidate to add additional behaviour by registering the Transfer object to listen for specific events. In this example I'll setup the transfer object to listen for the BeforeCreate and BeforeUpdate events. <cffunction name="configure" access="public" output="false" returntype="void">
<!--- register for transfer events --->
<cfset getTransfer().addBeforeCreateObserver(this)>
<cfset getTransfer().addBeforeUpdateObserver(this)>
</cffunction>
Once registered for these events, the Transfer object must implement the following methods. <cffunction name="actionBeforeCreateTransferEvent" access="public" returntype="void" output="false" hint="I set the created date before I am persisted for the first time.">
<cfargument name="event" hint="The event object" type="transfer.com.events.TransferEvent" required="Yes">
<cfset setCreatedDate(now())>
</cffunction>

<cffunction name="actionBeforeUpdateTransferEvent" access="public" returntype="void" output="false" hint="I set the created date before I am persisted for the first time.">
<cfargument name="event" hint="The event object" type="transfer.com.events.TransferEvent" required="Yes">
<cfset setModifiedDate(now())>
</cffunction>
Assuming that we have two properties on our Transfer object for CreatedDate and ModifiedDate, setting those values is now nicely de-coupled from a service or controller layers. Which is one of the reasons I really like using transfer decorators. Additionally, if you are in the habit of creating these properties on all your business objects, you could place these methods in a base decorator and call super.configure() within the configure() method of your transfer decorator.