Friday, 12 February 2010

I wanted to write some more sophisticated asserts in the Genome tests where the exception message is also tested for the error code (e.g. if the message contains #GENxxx).

In newer versions of NUnit there is an enhanced version of the ExpectedException attribute, where you can match the exception message in multiple ways. For example you can use a “contains” match to see if the right error code was mentioned in the exception message.

        [ExpectedException(typeof(GenomeException), ExpectedMessage = "GEN01253", MatchType = MessageMatch.Contains)]

As we were using an old version of NUnit (v2.2.6) I tried to upgrade to v2.5.3.9345 to make use of the new features. As soon as I did this my R# v4.5 failed to identify the ExpectedException at all.

To make it clear: even if I leave the ExpectedException attributes as they are (no new parameters like MatchType) the test runner does not recognize it, so all the existing tests using the ExpectedException attribute fail in the Resharper running environment after the upgrade of NUnit.

As you can see this is a major problem with R# that can be a show stopper (either to upgrade NUnit or to use R# for executing the tests), but it turns out that you can upgrade to R# v4.5.2 so that it supports the ExpectedException attribute of the newer NUnit versions *again*. I have found the info here: http://www.jetbrains.net/devnet/thread/281286

After installing the new version it seems to work again.  But It also turns out that the new parameterization with MatchType is still not supported. Trying the sample above the runner ignores the MatchType and claims that the message is not the same as specified. So you just get back the "basic" functionality of ExpectedException. Jetbrains “refused” to support this properly in the v4 branch and they promise improvements in v5.0 only: http://www.jetbrains.net/jira/browse/RSRP-43833

Get rid of the ExpectedException for the future anyway?

I'm not sure if this common sense, but there is a new way to expect the exception with NUnit. You can use the Assert.Throws method, where you pass the code that is supposed to throw the exception as delegate. This way you can explicitly mark "where" you expect the exception (while with the attribute it is not visible).

Also, you get back the exception in a strongly typed way and you can just write normal asserts about the exception. E.g. I can assert on the ErrorCode of the GenomeException. It is much cleaner compared to a String.Contains expressed in the ExpectedException attribute.

Another benefit is (considering the upgrade issues above) that you are more independent from the running environment, because the assertion is expressed as normal C# code. The runner does not need the “extra knowledge” unlike in the case of a special attribute.

[Test]
public void CreateObjectWithDefaultDiscriminatorReference()
{
...
var exception =
Assert.Throws<GenomeException>(() =>
{
Context.Current.Flush();
}
);

Assert.AreEqual("GEN0153", exception.ErrorCode);
Assert.That(exception.Message, Is.StringContaining("type discriminator"));
Assert.That(exception.Message, Is.StringContaining("not set"));
}
}

This is not a reason to rework all the existing tests, but I'd suggest to use this new technique for the future.

Friday, 12 February 2010 16:09:16 (W. Europe Standard Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
Comments are closed.