views:

42

answers:

1

Say I have a method

public void PrintStuff(string stuff, Color color, PageDimensions dimensions)
{
     Assert.IsNotNull("color");
     Assert.IsNotNull(dimensions);
     Assert.IsTrue(dimensions.width < 20.0);
}

and I have another method AnotherMethod() which is calling PrintStuff(). Let's assume PrintStuff() is defined in some interfaces that AnotherMethod() is using. The question is: when writing a unit test for AnotherMethod() how can I automate testing that AnotherMethod() does not pass any values into PrintStuff() that violate its assertions?

Something like:

printer.Expect(x => x.PrintStuff(null, null, null)).CheckAssertions();

The solution should support a change in assertions automatically.

+4  A: 

If PrintStuff is in an interface but your assertions are in a concrete class, who's to say the same assertions apply to all implementations? It sounds like what you really want is to give contracts to the interface rather than the concrete class. Obviously you can't do that in "normal" C# code...

Now, I'd suggest using Code Contracts which support contract inheritance, including interfaces. If you're using Visual Studio Premium or Ultimate editions, you can have compile-time static checking that you don't violate the assertions. Otherwise, you're back to mocking I believe. Now if you use mocking, I don't think the contracts will automatically be picked up, because they're usually applied using binary rewriting... but I'd expect the tooling in this area to improve reasonably soon. Of course, mocking usually involves specifying the inputs you expect anyway, so you should be able to make sure they're valid when you write your tests anyway.

You may also want to look at Pex which explores your code and tries to break it for you.

Jon Skeet
That's awesome. I guess I can just write a helper method to check the contracts with that thing.
HeavyWave