Thursday, April 29, 2004

Consider the problem writing a unit test for the IList.Add method. At first sight this is trivial (as an example, we check that IList.Add supports null reference):

[TypeFixture(typeof(IList))]
public class ListTest
{
   [Test("List accepts null values")]
   public void AddNull(IList list)
   {
       list.Add(null);
       ...
   }
}

Now what about the Readonly and the FixedSize wrapper of ArrayList. They implement IList, but calling IList.Add on them will throw a NotSupportedException. Using the classic ExpectedExceptionAttribute technique, the only solution is to create a special fixture for read-only and fixed size wrappers, and that involves a lot of code duplication.

To tackle this problem, I have added ConditionalExceptionAttribute, which expects an exception if a predicate is true. The predicate is define by a method of the fixture that returns a boolean. This solution is simple and avoids the duplicate of unit tests when possible. Let's addapt the example with the new decorator:

[TypeFixture(typeof(IList))]
public class ListTest
{
   public bool IsReadOnly(IList list)
   {
       return list.ReadOnly;
   }

   [Test("List accepts null values")]
   [ConditionalException(typeof(NotSupportedException),"IsReadOnly")]
   public void AddNull(IList list)
   {
       list.Add(null);
       ...
   }
}

When the test will be executed, if list.ReadOnly is true, the framework will expect to receive a NotSupportedException, but if it is false, he will not check for exception. Note that the parameters of the predicate must match the parameters of the test method and it must return a bool.

posted on Thursday, April 29, 2004 11:35:00 PM UTC  #    Comments [3]
Tracked by:
"peachez 16" (online) [Trackback]
Monday, June 06, 2005 6:10:09 PM UTC
Wow...this looks very powerful.
<br>
<br>A related capabilitiy I've wanted for a long time was to have a fine-grained check when an exception is thrown, like the ability to test if the message is a certain one. This would let me differentiate between different ApplicationExceptions when a test throws more than one, to be really sure the test was successful.
<br>
<br>[ExpectedException( typeof(ArgumentException), &quot;some regular expression&quot; )]
<br>[Test] public void Method()
<br>{
<br> ... Code that throws multiple ArgumentExceptions, only one we expect to see
<br>}
<br>
<br>This style of test says it expects an ArgumentException to be thrown by the test code, and the test can only pass if the regular expression value matches against the message of the exception. If no ArgumentException is thrown, or the message of the exception doesn't match the regular expression, then the test fails.
Doug de la Torre
Monday, June 06, 2005 6:10:09 PM UTC
That is totally possible. Doug, this is the kind of ideas that you should post as a request in the <a title="MbUnit, Generating Unit Testing and Model Based Testing Framework for .NET Framework" href="http://mbunit.tigris.org" target="_blank">MbUnit</a> issue tracking (or use the mailing list).
Jonathan de Halleux
Monday, June 06, 2005 6:10:10 PM UTC
Peli's Blog
Comments are closed.