August 30th, 2006

Wednesday, August 30th, 2006

Thinking About Assert Syntax

I’ve been using the development of NUnitLite (coming soon!) as an excuse to try out alternatives to the standard NUnit syntax for Asserts.

NUnit allows us to write things like…

Assert.AreEqual( expected, actual );
Assert.Greater( x, 5 ); Assert.Less( x, 10 );
Assert.IsTrue( x > 5 && x < 10 );

The last is instructive: if it fails, the message simply tells us that True was expected but the value was actually false. Any more intelligent message must be supplied as an argument...

Assert.IsTrue( x > 5 && x < 10, "Value of x must be < 5 and > 10" );

An alternative idea, borrowed from NMock, is to encapsulate the comparison in some sort of an object. Then you can write things like...

Assert.That( actual, new EqualsMatcher( expected ) );
Assert.That( x, new AndMatcher( 
	new (GreaterThanMatcher( 5 ), new LessThanMatcher( 10 ) ) );

Of course, these aren't too easy to type, but with the addition of some helper methods and the use of operator overloading, we can replace it with

Assert.That( actual, Is.EqualTo( expected ) );
Assert.That( x, Is.GreaterThan( 5 ) & Is.LessThan( 10 ) );

That pretty much covers what I've implemented so far. I'm not fully satisfied with the expressiveness of this syntax, though. It's clear but a bit wordy. I'm thinking of going back to a set of inherited methods to either replace or supplement the methods of the Is class. That might give me something like this...

Assert.That( actual, eq( expected ) );
Assert.That( x, gt( 5 ) & lt( 10 ) );

So what do folks think? Is it worth pursuing this syntactic approach? Or should we just go back to Assert.AreEqual and friends?

Charlie