Photo from Chile

Faking ColdFusion Component Types (and a Quick Way to Confuse ColdFusion)

MightyMock (MM) is a mocking framework for ColdFusion that is bundled with MXUnit. It allows you to create mocks, which are fake instances of ColdFusion components, for use in unit tests. More information on what MightyMock is and how you can use it to create awesome unit tests can be found on the MXUnit Wiki.

One thing that MM allows you to do is to create typesafe mocks, which are mock objects that ColdFusion will recognize as being of a specific type. Why might you need to do that? Let's say you have a setter defined in a component into which you want to pass your mock object, and that setter expects an argument of a certain type. For example, consider this setter in a Customer.cfc component:

view plain print about
1<cffunction name="setValidator" access="public" returntype="void">
2    <cfargument name="validator" type="model.util.validator" />
3    <cfset variables.validator = arguments.validator />

If we want to create a mock object and pass it into that method, it needs to have a type of model.util.validator or ColdFusion will throw an error as soon as we call setValidator(). MM allows us to create such a mock using the optional second parameter of the mock() method that is available in MXUnit. The code to create a test for our Customer component using a typesafe Validator mock would look something like this:


I'm Invading Your Airwaves Again

Yes, once again I've been interviewed for a ColdFusion podcast, and this time it's CFHour. Dave and Mike allowed me to wax poetically about a wide range of topics including ValidateThis, my validation framework for ColdFusion objects, the upcoming cf.Objective() conference and the pre-conference training that will be available, Model-Glue, specifically some of the new features that will be included in version 3.2, MXUnit, again talking about what's coming in version 2.0, and Dave also tricked me into weighing in on the CFBuilder debate.

It was a lot of fun, and I really appreciate being given the opportunity to let people know about all of this great stuff that is available to the ColdFusion community. If you don't mind listening to my Canadian accent for close to an hour, I encourage you to give it a listen. It's available via iTunes, and can also be listened to or downloaded directly from the show page.

New Stuff for MXUnit, Model-Glue and ValidateThis on the Horizon

I've been extremely busy over the past couple of months on a number of projects, both for clients and open source, which has lowered my blog post output to approximately zilch.

I thought I would write a quick note about some items that I've been working on, and that should hopefully see the light of day in the ColdFusion open source world in the near future.

MXUnit Mocking Integration

Bill Shelton, of MXUnit fame, has written a mocking framework called MightyMock that has been close to being released for quite some time. I've used it and I liked it a lot. Bill and I discussed integrating it with MXUnit itself, to make mocking super easy for developers using MXUnit, and during the discussions we realized that it would be nice if MXUnit could support generating mocks via any framework, not just MightyMock. I set out to build a plugin architecture that would allow for any ColdFusion based mocking framework to be used with MXUnit. Thus far I have it working with MightyMock, ColdMock and MockBox. We're still working on the final bits and pieces, but if anyone is interested in giving it a try let me know and I can point you in the right direction.

Model-Glue ColdFusion 9 ORM Support

If you're a user of the Model-Glue MVC Framework you're probably aware of the fact that a couple of ColdFusion ORMs (namely Transfer and Reactor) can be used quite seamlessly with the framework via what's referred to as an ORM Adapter. This allows Model-Glue developers to take advantage of Generic Database Messages (GDMs), which provide for automatic CRUD (creating, reading, updating and deleting records in database tables) as well as basic listings. These GDMs also form a part of a feature called Scaffolds, which takes the automation even further by generating view and controller code for maintaining database tables. Using Scaffolds you can get a complete CRUD solution up and running in a matter of minutes.

With the release of ColdFusion 9 there's a new ORM player in the game, namely ColdFusion itself, with its new Hibernate integration. Dennis Clark and I have been developing a Model-Glue ORM adapter for ColdFusion 9's built-in ORM and it is nearly ready to be released. If you are interested in taking a look at it, or willing to help with testing it, please let me know.

The Model-Glue Documentation has more information available on both Generic Database Messages and Scaffolds.

ValidateThis CF9/ColdBox Sample Application

John Whish has been kind enough to contribute some bug fixes and enhancements to the ValidateThis core, as well as the ColdBox plugin. He's also been working on a ValidateThis/ColdBox 3/CF9 ORM sample application, which I plan to contribute to as well and should be made available in the near future.

ValidateThis CFWheels Integration

Mike Henke and I have been working on getting ValidateThis to work with the ColdFusion on Wheels framework, which just celebrated its 1.0 release. Although ValidateThis is designed to be totally framework agnostic (meaning it can be used with any framework without modification), because it is designed to validate ColdFusion objects, it relied on the fact that those objects would expose getters for each of their properties. That is standard practice throughout most of the CF world, but Wheels is a bit different. Its objects do not have getters for their properties, so the server-side validations were unable to determine the values of any properties, which rendered them useless.

Thanks to the encapsulation afforded by a decent object oriented design, I was able to enable ValidateThis to work with these new types of objects (which don't have getters) with a couple of minor code changes to the framework. Mike and I now have a version of ValidateThis that works with traditional objects as well as with "Wheels style" objects. Mike is also working on a new ValidateThis sample application, using CFWheels. Once we're done testing and have a decent sample application this new version of ValidateThis will be released, along with the new sample.

ColdFusion 9 ORM Training

Finally, I'd just like to mention that Mark Mandel and I will be delivering a comprehensive two-day, hands-on course covering Developing Applications with ColdFusion 9's new ORM features as a pre-Conference workshop at cf.Objective() this year. The course will run from April 20th to April 21st, 2010. Much more info will be available soon.

Happy Holidays everyone!

Using MXUnit's injectMethod() to Reverse an injectMethod() call

I encountered a situation today in which I wanted to reverse the effects of an injectMethod() call in an MXUnit ColdFusion unit test. Here's some code that resembles my test case:

view plain print about
1<cfcomponent extends="mxunit.framework.TestCase">
3<cffunction name="setUp" access="public" returntype="void">
4    <cfscript>
5        variables.CUT = CreateObject("component","myComponentUnderTest");
9<cffunction name="test1IsActuallyProperlyNamed" access="public" returntype="void">
10    <cfscript>
11        injectMethod(variables.CUT, this, "overrideVerifyToTrue", "verify");
12        assertTrue(variables.CUT.aMethodThatWantsVerifyToReturnTrue());
16<cffunction name="test2IsActuallyProperlyNamed" access="public" returntype="void">
17    <cfscript>
18        injectMethod(variables.CUT, this, "overrideVerifyToTrue", "verify");
19        assertTrue(variables.CUT.anotherMethodThatWantsVerifyToReturnTrue());
23<cffunction name="test3IsActuallyProperlyNamed" access="public" returntype="void">
24    <cfscript>
25        injectMethod(variables.CUT, this, "overrideVerifyToTrue", "verify");
26        assertTrue(variables.CUT.aThirdMethodThatWantsVerifyToReturnTrue());
30<cffunction name="test4IsActuallyProperlyNamed" access="public" returntype="void">
31    <cfscript>
32        assertTrue(variables.CUT.aMethodThatWantsVerifyToBehaveAsCoded());
36<cffunction name="overrideVerifyToTrue" access="private" returntype="Any" hint="will be used as a test-time override with injectMethod()">
37    <cfreturn true />

From the above we can see that the first three tests want the method called verify() in the Component Under Test (CUT) to return TRUE, so we use injectMethod() to take a fake method (overrideVerifyToTrue), and use it to replace the actual verify() method in the CUT. The last test wants the verify() method in the CUT to behave as it's coded, so it doesn't call injectMethod(). This all works, but it introduces some duplication that I'd rather not have; I have to issue the same injectMethod() call in most of the tests. To remove that duplication I'd like to be able to move the call to injectMethod() into the setup() function. But, if I move injectMethod() into the setup() function, I'd need a way to "undo" the injectMethod() call in the final test.


Some Benefits of Unit Testing

I must start by saying that, as much as I like option groups, I love Unit Testing. I had written previously that I Like Unit Testing, but that brief infatuation has blossomed into a full blown love affair. I have two people/groups to thank for that, Paul Marcotte and the MXUnit Team, who produce an excellent suite of unit testing tools for ColdFusion.

I met with Paul in the Toronto airport a couple of weeks ago during a brief stopover (his, not mine) and he walked me through his current methodology for unit testing. He really cleared up some areas of confusion for me, and essentially handed over a set of practices that makes everything oh so easy. He's been blogging about his technique in a series that I heartily recommend.

And what can I say about MXUnit that hasn't already been said? It totally rocks! The Eclipse Plugin is da bomb! If you haven't checked it out, do so. Now. 'Nuff said.

So when do I get to hear about "Some Benefits of Unit Testing", you may be asking? Read on.


I Like Unit Testing

I never imagined that I'd say those words, but they're true. I must start by admitting that I wrote my first unit test a few days ago. I know, I'm bad, I should have been doing this for years. I've known about unit testing for a long time, I've been reading more and more about it, and listening to speakers at conferences extol its virtues. But somehow I just couldn't get my a$$ in gear. It just seemed like too much extra work. And as a sole developer working on relatively small projects I was able to get away with not doing it.

Anyway, I read a blog post a few days ago that inspired me to take the plunge. The post describes unit testing with CFUnit, but I'd been hearing a lot of good things about MXUnit, so I decided to give that a try.