Pages

Wednesday, September 1, 2010

Using Mock Objects to Test Functions With Named Arguments in MXUnit

Today I was writing some code that dynamically called a method setter on an object. While all of the dump output looked like what I was expecting my MXUnit tests kept failing and I couldn't figure out why. Then I realized that I was using a cfinvoke statement to call the setter and that always uses named parameters to set the argument values. As soon as I added the argument names to my tests I got my happy little green bar.

For example, this is my component that calls a setter dynamically using cfinvoke:
<cfcomponent>
 <cffunction name="SetDynamicProperty" 
    access="public" 
    output="false" 
    returntype="void" 
    hint="I set a value on a object dynamically">
  <cfargument name="theValue" type="any" />
  <cfargument name="theProperty" type="string" />
  <cfargument name="theObject" type="any" />
  <cfinvoke component="#arguments.theObject#" method="Set#arguments.theProperty#">
   <cfinvokeargument name="#arguments.theProperty#" value="#arguments.theValue#">
  </cfinvoke>
 </cffunction>
</cfcomponent>

Here is the first test I wrote:

As a side note you might notice that my tests are written in script format while my CUT is written in tag format. This is because my production environment at work is CF8 but I use CF9 locally and write my tests in script to practice my CF9 skills

component extends="mxunit.framework.TestCase" 
{
 function testSetDynamicProperty_should_call_SetFirstName(){
  var NamedArguments = new NamedArguments();
  var MockTestObject = mock();
  
  //create the mock behavior
  MockTestObject.SetFirstName('Ryan');
  
  NamedArguments.SetDynamicProperty("Ryan","FirstName",MockTestObject);
  MockTestObject.verify().SetFirstName('Ryan');
 }
}

The above test produced this result:


Here is my new test using named arguments:

component extends="mxunit.framework.TestCase" 
{
 function testSetDynamicProperty_should_call_SetFirstName(){
  var NamedArguments = new NamedArguments();
  var MockTestObject = mock();
  
  //create the mock behavior
  MockTestObject.SetFirstName(firstname='Ryan');
  
  NamedArguments.SetDynamicProperty("Ryan","FirstName",MockTestObject);
  MockTestObject.verify().SetFirstName(firstname='Ryan');
 }
}

The above test gives me the happy little green bar: