Matchers

Prior to version 2.0, expected and actual behaviour was determined by performing equality checks between the method signatures of the expected calls and the actual calls. All function parameters were checked for direct equality. (Objects/components were the exception and were just checked for type.)

Setting expected behaviours would work fine as long as the method under test doesn't pass internally generated data, such as a date or a UUID, into the mock.

As you can see, this behaviour can be limiting. Take the example of a CacheManager object that sets a creation date on a mocked CacheableItem.

<cfinterface name="CacheableItem">
<cffunction name="setCacheDate" />
</cfinterface>

<cfcomponent name="myItem">
<cffunction name="setCacheDate">
...
</cffunction>
</cfcomponent>

<cfcomponent name="CacheManager">
<cffunction name="add">
<cfargument name="cacheItem" required="yes" type="CacheableItem">

   <cfset arguments.cachedItem.setCacheDate( now() ) />

   <!--- add item to cache, etc. --->
</cffunction>
</cfcomponent>

Now we attempt to write a unit test for the CacheManager.

<cfcomponent name="testCacheManager" extends="mxunit.framework.TestCase">
<cffunction name="testAdd">
<cfset mf = createObject( "component", "easymock.MockFactory" ) />
<cfset ciMock = mf.createMock( "myItem" ) />
<cfset mgr = createObject( "component", "CacheManager" ) />

<cfset mf.expect( ciMock.setCacheDate( now() ) ) />

<cfset mf.replay( ciMock ) />

<cfset mgr.add( ciMock ) />

<cfset mf.verify( ciMock ) />
</cffunction>
</cfcomponent>

Everything looks like it's in order. We're calling the setCacheDate() function and passing it the same value as in the CacheManager. However, when this test runs it will fail (unless your computer is infinitely fast). Why? Because the timestamp value returned from now() is not the same as the value passed when the test calls the add() function. So how do you tell the mock to expect something that "matches" a given input, but doesn't have to "equal" that input?

This is where matchers come in to play. Version 2.0 introduces matchers as a way to manage expected parameters when a specific data match is not necessary or impossible to reproduce.

In the above example, we would change the expect() call on the ciMock to use one of the matchers provided by CFEeasyMock

...
<cfset mf.expect( ciMock.setCacheDate( mf.after( '1900-01-01' ) ) ) />
...

The mf.after() function call returns a DateMatcher that will return true for any value on or after January 1, 1900. If no matcher is specified, the value passed to the mock function call during record phase is wrapped in a matcher that matches based on equal values. So the following two expectations are identical to CFEasyMock in record mode:

<cfset mf.expect( mock.setName( "Rumplestiltskin" ) ) />

<cfset mf.expect( mock.setName( mf.eqs( "Rumplestiltskin" ) ) ) />

For a complete list of matchers see the Appendix. You can also create your own matchers by implementing the IMatcher interface. There are three methods that the interface requires to be implemented.

matches( any ) This function is called to determine if the matcher's instance value matches the value passed.

asString() This function is called to display only the matcher parameter as a string. The simplest return string would be the matcher's instance value. Other matchers have more complex return strings, as in the case of the DateMatcher and NumericMatcher.

isEqual( IMatcher ) This function is called to determine if two matchers are equal. The function should return whether or not two matchers are equal based on matcher component type as well as the matcher instance values.

Comments
Erika's Gravatar When I look to buy a pair of shoes, <a href="://www.toryburch-salestore.com/flats_c1"><strong>Tory Burch flat shoes</strong></a> I generally try to shop around <a href="://www.toryburch-salestore.com/office_v220/handbags_c8"><strong>formal clutch purses</strong></a> for the best possible deal. The <a href="://www.toryburch-salestore.com/wedges_c3"><strong>cute wedge shoes</strong></a> internet gives us some great ways <a href="://www.toryburch-salestore.com/flip-flops_c4"><strong>flip flop store</strong></a> to make savings on shoes and other online purchases.
# Posted By Erika | 3/18/12 8:46 PM
discount fitflops's Gravatar 9250: bright blue in the summer look let a person have relaxed feeling, design also want to be different can be youth students chosen.

9252: double color watercolor rendering process of add artistic fascination.

9273: red and black, vigor 4 shoot in his blunt.

P8 ~ 9: urban rangers m
# Posted By discount fitflops | 6/26/12 3:10 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.5.006. | Protected by Akismet | Blog with WordPress