I have been making a little toy web application in C# along the lines of Rob Connery's Asp.net MVC storefront.
I find that I have a repository interface, call it IFooRepository, with methods, say
IQueryable<Foo> GetFoo();
void PersistFoo(Foo foo);
And I have three implementations of this: ISqlFooRepository, IFileFooRepostory, and IMockFooRepository.
I also have some test cases. What I would like to do, and haven't worked out how to do yet, is to run the same test cases against each of these three implementations, and have a green tick for each test pass on each interface type.
e.g.
[TestMethod]
Public void GetFoo_NotNull_Test()
{
IFooRepository repository = GetRepository();
var results = repository. GetFoo();
Assert.IsNotNull(results);
}
I want this test method to be run three times, with some variation in the environment that allows it to get three different kinds of repository. At present I have three cut-and-pasted test classes that differ only in the implementation of the private helper method IFooRepository GetRepository(); Obviously, this is smelly.
However, I cannot just remove duplication by consolidating the cut and pasted methods, since they need to be present, public and marked as test for the test to run.
I am using the Microsoft testing framework, and would prefer to stay with it if I can. But a suggestion of how to do this in, say, MBUnit would also be of some interest.
Create an abstract class that contains concrete versions of the tests and an abstract GetRepository method which returns IFooRepository. Create three classes that derive from the abstract class, each of which implements GetRepository in a way that returns the appropriate IFooRepository implementation. Add all three classes to your test suite, and you're ready to go.
To be able to selectively run the tests for some providers and not others, consider using the MbUnit '[FixtureCategory]' attribute to categorise your tests - suggested categories are 'quick' 'slow' 'db' 'important' and 'unimportant' (The last two are jokes - honest!)