UnitTest Utility Library Update
A number of readers of this blog have let me know that they have adopted the UnitTestBase and DatabaseUnitTestBase classes that I originally demonstrated from the Summer of NHibernate screencast series as a simple means of facilitating their writing of unit tests. This is great news as I’m glad others have been finding value in the library and I had of course encouraged anyone interested to try it out and adopt it if it met their needs.
These abstract base classes (from which consumers would derive their concrete test fixture classes) provide several convenience facilities that make it slightly easier for a developer to write tests that leverage the RhinoMocks mock objects framework as well as significantly easier to write tests that leverage the NDbUnit database-state-management framework when writing database-interaction unit tests (ok, technically these are integration tests, but you get the point).
Some of these conveniences are…
- built-in access to the RhinoMocks MockFactory without needing to instantiate one (the base class contains a member field that contains a pre-constructed MockFactory instance)
- simple convention-over-configuration defaults that allow a simple set of conventions for data files, schema files, and other elements to quickly setup, teardown, and reset your database contents to support your database integration testing
- convenience methods for interacting with the database and data to perform common repetitive tasks with ease
- Unit test type enums for annotating your tests in a 100% consistent manner so that build scripts, etc. can properly filter different kinds of tests to run them in different build configurations (e.g., on an automated CI server, etc.)
The Challenge
One of the challenges with #1 above is that this means that the UnitTest Utility Library has a dependency on the RhinoMocks framework. Its not a huge dependency since there is little integration between the two, but when it comes to a compile-time dependency, there is no such thing as a ’small’ dependency. This means that when an updated version of RhinoMocks is released, an updated version of the UnitTest Utility needs to be compiled against the new RhinoMocks release. Such was the case when the RhinoMocks 3.5 RC1 build was released and it is again the case now that the final RTM build of RhinoMocks 3.5 has been released (as was the case earlier this week).
To satisfy the needs of those that have chosen to adopt the UnitTest Utility, I have now rebuilt the library against the RhinoMocks 3.5 RTM release and am making it available for download to anyone who is interested. (BTW, Sudarshan, this invitation doesn’t extend to you for reasons clear to anyone who ready this post from last week).
There are actually now two RhinoMocks releases called v3.5, one that targets the .NET 2.0 framework and another that targets the .NET 3.5 framework. This unfortunate situation (although I completely agree with Ayende’s reasoning for why he did this) has lead to the co-release of "RhinoMocks 3.5 for .NET 2.0" and "RhinoMocks 3.5 for .NET 3.5". I guess you know you’ve made it big-time when your own product versions are every bit as confusing as Microsoft’s ("C# 3.0 for .NET 3.0", "C# 3.0 for .NET 3.5 on the 2.0 CLR", etc.) ![]()
In any case, I am also releasing two builds of the same UnitTest Utility, one for .NET 2.0 (integrated with RhinoMocks 3.5 for .NET 2.0) and the other for .NET 3.5 (integrated with RhinoMocks 3.5 for .NET 3.5) that can be reached from the following download links…
- UnitTestUtility for .NET 2.0 (RhinoMocks 3.5 for .NET 2.0)
- UnitTestUtility for .NET 3.5 (RhinoMocks 3.5 for .NET 3.5)
A few Goodies snuck in
In addition to simply rebuilding the utility for the new RhinoMocks release, I’ve also taken the opportunity to introduce two new additional convenience methods to the UnitTestBase class:
GetInstanceFieldValue(…)
SetInstanceFieldValue(…)
Just as their names suggest (another point in favor of ‘intention-revealing-interfaces’
), these two complimentary methods allow your test fixture class to use the .NET reflection API to get and set both public and private fields in any class. While reflection is generally frowned-upon in production code as being a performance drag, using it in unit tests to either get or set values on classes under test can be extremely useful to avoid the need to create public properties on objects just to ‘inspect’ their values at test-time, or perhaps to set a private field in the same way something like NHibernate might — by bypassing any public setter logic, etc.
To be clear, good unit test techniques suggest (and I generally agree) that if you are testing the internal, non-public aspects of your classes then you tend to be writing brittle unit tests that test the wrong things, but I believe in giving developers the tools they need and then trusting that they will do the right thing with them. And so I’m adding these two methods to the base class to support easily testing to ensure that simple things like constructor-injected dependencies end up in the right place inside a class’ private field(s).
Since the methods are internal and virtual, if you don’t like them at all then simply either ignore them or override them in your derived concrete class and fill their method bodies with code that does nothing. Your choice.
Also, as mentioned in this post when I released the updated build for RhinoMocks 3.5 RC1, both of these downloads also contain a CHM help file that documents (pretty clearly, if I say so myself
) the entire reasonably simple API for this library of base classes so anyone interested is encouraged to download either of the packages from the preceding links to review the compiled HTML help file contents.
As always, any comments, feedback, etc. is much-appreciated. Have fun and happy coding~!


I’m also using your little utility, but unlike Sudarshan, in it’s original form

October 10th, 2008 at 4:47 amJust wanted to thank you on the effort you put in Summer of NHibernate series. Can’t wait for Autumn of Agile
Hm, I just upgraded my test project to use new versions of Microdesk.Utility.UnitTest and Rhino.Mocks, and the tests are failing with this exception:
System.IO.FileLoadException: Could not load file or assembly ‘Rhino.Mocks, Version=3.5.0.2, Culture=neutral, PublicKeyToken=0b3305902db7183f’ or one of its dependencies. The located assembly’s manifest definition does not match the assembly reference. (Exception from HRESULT: 0×80131040)
Same exception using 3.5 and 2.0 versions. I’ve also tried to create a new test project referencing those assemblies. Same exception again. Is it possible that you have added the wrong version of Rhino.Mocks to zip files?
October 10th, 2008 at 5:30 am@Miroslav:
That sure sounds like what happened. I just updated the ZIP files again (same filenames, same links) so try again and advise results. The ‘confusion’ is made worse by the fact that the RhinoMocks DLL that was the RC1 release was stamped v3.5.0.2 but that both of the RTM versions are tagged with v3.5.0.1337 which would lead one to believe that they are OLDER than the RTM build (which obviously cannot be the case).
Any any event, try again and let me know if this resolves it for you; sorry for any confusion from this — at least they are small downloads
October 10th, 2008 at 6:40 amThis time it’s working as advertised
October 10th, 2008 at 8:05 amBoth versions are tested. Thanks for a quick update.
@Miroslav:
Thanks for the feedback, sorry about the mixup. It turns out that I think the correct version of the RhinoMocks dll was included in the prior ‘broken’ packages I posted, but since I failed to hit CLEAN SOLUTION between builds, the change to just a dependent DLL in your solution doesn’t result in a recompile when issuing a BUILD action. I’m not sure whether I should consider this a ‘bug’ in VS or a ‘feature’, but its certainly somewhat unexpected since I (personally) think the build action should trigger a recompile cycle on any project that has had one or more of its binary dependencies changed rather than just on projects that have their source code changed.
In any event, I appreciate the feedback and the free QA services
October 10th, 2008 at 9:23 am@Steve
Anytime
October 10th, 2008 at 9:58 am