Switching to MbUnit
For the longest time now, I’ve been a fan of MbUnit, but never really used it on a real project. In part, I stuck with NUnit despite MbUnit’s superiority because NUnit was the defacto standard.
Well you know what? Pretty much every company or client I end up moving to has not had unit testing in place before I arrived. I’ve always been the one to introduce unit testing. So on my latest project, when I finally meet another developer who writes unit tests, and he is using MbUnit, I decided to make the switch.
And that, my friends, was a great decision… Why?
TypeFixture
Say you write an interface IFoo
(though it could just as easily have
been an abstract class or any base class for that matter). You then
proceed to implement a couple implementations of IFoo
. Wouldn’t it be
nice to write some unit tests specific to the interface? Here’s how you
do it in MbUnit.
interface IFoo {}
class Bar : IFoo {}
class Baz : IFoo {}
[TypeFixture(typeof(IFoo), “Tests the IFoo interface.”)]
publicclass IFooTests
{
[Provider(typeof(Bar))]
public Bar ProvideBar()
{
returnnew Bar();
}
[Provider(typeof(Baz))]
public Baz ProvideBaz()
{
returnnew Baz();
}
[Test]
publicvoid TestIFoo(IFoo instance)
{
//Test that the IFoo instance
//Behaves properly.
}
}
What you are seeing is a TypeFixture
which is a type of TestFixture
that is useful for testing an interface. There is only one test method
TestIFoo
. However you should notice that it takes in a parameter of
type IFoo
.
This deviates from the typical NUnit test which does not allow any
parameters. So just who is passing the test that parameter? The other
methods in the fixture that have been marked with the Provider
attribute. The test method is called once for every provider. The
provider methods simply instantiate the concrete instance of the
interface you are testing. So the next time you implement the interface,
you simply add another provider method. Pretty sweet, eh?
Row Based Testing
I already wrote a
post on the RowTest
attribute for MbUnit. It supports a very common test paradigm of using
the same method to test a wide variety of inputs.
Test Runner
Matt Berther shows how easy it is to write an
executable that will
run all your unit tests.
RollBack Attribute
Attach this attribute to a test method and MbUnit makes sure that any
database transactions are rolled back at the end of the test. There is
an implementation of a RollBack
attribute for
NUnit out there, but
the extensibility model is tricky, as I found I couldn’t get the
RollBack attribute to work with an ExpectedException
attribute.
And More…
MbUnit also has test attributes for repeating a test and repeating a
test on multiple threads. It also has a test fixture designed to test
custom collections that implement IEnumerable
and IEnumeration
.
For more information, check out this Code Project article and the MbUnit wiki.
In the near future, I’ll be switching the unit tests for Subtext to use MbUnit. And assuming Dare and Torsten are ok with it, the unit tests for RSS Bandit.
Comments
One response