Since this is my first blog post ill start out small enough.
Recently we have migrated our unit test from NUnit into MSTest. Although by large the transition was quite smooth, one of the more annoying issues is the different behavior of the ExpectedException attribute.
An intended design or an oversight by MS?
I would (wishfully) think the latter is the case. But in any case I would say its a Mistake.
In any case, since MsTest does not support asserting on the exception message, we had to revise some of the tests. The revision itself is quite simple, just need to wrap the test code with try catch clause. Something like:
[TestMethod]
public void SomeTest()
{
try
{
//The test code:
//...
//...
Assert.Fail("We should not get here");
}
catch(SomeExceptionType ex)
{
Assert.AreEqual("Expected Message",
ex.Message);
}
}
However after doing this for a couple of tests we have managed to come up with a slightly better pattern:
[TestMethod]
[ExpectedException(typeof(SomeExceptionType))]
public void SomeTest()
{
try
{
//The test code:
//...
//...
}
catch(SomeExceptionType ex)
{
Assert.AreEqual("Expected Message",
ex.Message);
throw;
}
}
Although the difference is quite minor, still we found the second version much more expressive and readable.
To conclude, there’s a lesson to be learnt here. When trying to replace a well used framework its best to make sure that the transition will be as easy as possible (Unless you are MS and can get away with this).
5 comments:
What if the exception does not occur though? The test will still pass...
In the first example you have an Assert.Fail("..."); that makes sure that if the exception is not thrown the test will fail.
In the second example the test is decorated by the ExpectedException attribute which means that the test will fail if no exception is thrown.
(BTW Dror has showed another way of doing it by extending the Assert class check out this link: http://blog.typemock.com/2009/03/how-to-check-exception-message-using-ms.html)
@Lior "BTW Dror has showed another way of doing it by extending the Assert class..."
Actually, the example on that link does not extend the Assert class, unfortunately. What it does is simply create a new class called MyAssert that takes an Action and a message to check. It's a bit of a cludge but would work, unless you wanted to return a value, in which case you could define a func version.
I found this blog post which explains how to implement your own attribute checking for exception and it's attribute:
http://mariuszwojcik.wordpress.com/2011/04/16/mstest-expectedexceptionwithmessageattribute/
MSTest ExpectedException and How to test Exceptions http://www.shirmanov.com/2011/06/mstest-expectedexception-and-how-to.html
Post a Comment