How I set up CFEasyMock

Tuesday, June 3, 2008

CFEasyMock is the latest mock framework for CF. It's based on the popular EasyMock framework for Java and is quite a nice port from what I can tell. If you set it up exactly as the author has packaged it, and if you already have cfcunit installed, then you should have no problems getting started. If you're like me and aren't keen on the way it's distributed, and if you want to change CFEasymock's own unit tests to use MXUnit, here's what to do Changing directory structure I don't like how it has 4 separate directories for a single framework. It's built like so:
  • easymock
  • reflect
  • samples
  • test
Why are samples and test outside of easymock? I don't know. Why is reflect outside of easymock? because it's technically a separate project. OK, fair enough. I'll live with that (for now). So here's what I did:
  1. Download latest cfeasymock
  2. copied reflect into my webroot
  3. copied easymock into my webroot
  4. copied test and sample into that easymock directory
  5. copied easymock word doc into easymock directory
  6. copied reflect word doc into reflect directory
  7. created a new eclipse project for the easymock directory
Setting it up to use MXUnit
  1. In Eclipse, selected the "sample" and "test" directory
  2. Hit CTRL-H to pop up the search box
  3. enter org.cfcunit.framework.TestCase into the "Containing Text" box.
  4. Filter on *.cfc
  5. Select "Selected Resources" radio button if it's not already selected
  6. Click Replace button
  7. Enter mxunit.framework.TestCase into the "With" box.
  8. Click "Replace All"
Running the tests in MXUnit As of now, all but two of the tests should go OK. The two that won't are in ResultTest.cfc because they use an assertion from CFCUnit that MXUnit doesn't copy verbatim, the "AssertClass" assertion. MXUnit has an AssertIsTypeOf(), though, so we'll just swap the two. In testCreateReturnResult, change the cfset assertClass.... to this: <cfset assertIsTypeOf(returnResult, "easymock.Result", "value returned from createThrowResult() is not of type easymock.Result" ) /> In testCreateThrowResult, change the cfset assertClass to this: <cfset assertIsTypeOf(throwResult, "easymock.Result", "value returned from createThrowResult() is not of type easymock.Result" ) /> Now, all tests should pass when you run them in MXUnit. Running the "Samples" In the Samples directory there are two test cases: TestClassUnderTest and TestUser. If you run them in the directory structure we've just created, they'll fail with a "Could not find the ColdFusion Component or Interface "sample.User".... and so on. So we just need to prefix the "sample" with "easymock." to get the right component path.
  1. In Eclipse, highlight the "sample" directory
  2. Hit CTRL-H, do a replace-all of "sample." with "easymock.sample."
That'll get "TestUser" to run OK. From there, I tried running the TestClassUnderTest tests, but I got errors about "Could not convert the value of type class coldfusion.runtime.TemplateProxy to a boolean. And for now, I don't have the time to debug it. If I get some time I'll post back here. With that bit of cleanup out of the way, I'm ready to start easymocking. I look forward to having this tool in the toolbelt. As I get time, I hope to add more posts on using easymock in the real world. --marc


bill said...

would be nice to be able to configure what kind of exceptions cfeasymock throws on failure, so, they are not picked up as errors, but rather verification failures.


Marc Esher said...

or maybe set up mxunit so that it has a configurable list of exceptions that it considers failures?