No doubt Visual Studio provides extensive Unit Testing framework. Plus there are feature-rich third-party frameworks (e.g. NUnit) available for Unit Testing your .NET code.
However, I was disappointed by lack of .NET support for Assertions. As you might be able to recall, Assertions guarantee that a given expression evaluates to a true value. If it doesn’t, the Assertion fails and languages have their own ways of dealing with failed assertions.
Standard C library provides a macro called assert (see assert.h) which prints an error message and halts the program execution when an Assertion fails. Java also provides a similar construct (check this out).
.NET however, does not provide out-of-the-box support for something similar. There is an Assert method in System.Diagnostics.Debug class. However, that method just prints a message when the Assertion fails, and the program executes forward normally. Assertions on the other hand are used when a condition failing signifies a problem with the code, that should deviate the execution of the code in some way, from its normal path.
In my case, I was working in a web-app, and did not want to resort to the exotic Unit testing frameworks just to ensure that a particular condition is always met. I wanted an exception to be thrown if the condition failed. Moreover, I wanted to Assert conditions only during debugging while testing my code. Failing to find something similar in .NET, I wrote the following class (with some inspiration from a csharp-station article):
{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }public class Assert
{
#region Test Methods
[System.Diagnostics.Conditional(“DEBUG”)]
public static void Test (bool condition)
{
if (condition) { return; }
throw new AssertionException(“Assertion failed.”);
}
[System.Diagnostics.Conditional(“DEBUG”)]
public static void Test (bool condition, string message)
{
if (condition) { return; }
throw new AssertionException(“Assertion failed: ‘” + message);
}
[System.Diagnostics.Conditional(“DEBUG”)]
public static void Test (AssertionCallback callback)
{
if (callback()) { return; }
throw new AssertionException(“Assertion failed.”);
}
[System.Diagnostics.Conditional(“DEBUG”)]
public static void Test (AssertionCallback callback, string message)
{
if (callback()) { return; }
throw new AssertionException(“Assertion failed: ‘” + message);
}
[System.Diagnostics.Conditional(“DEBUG”)]
public static void Test<T> (AssertionCallback<T> callback, T obj)
{
if (callback(obj)) { return; }
throw new AssertionException(“Assertion failed.”);
}
[System.Diagnostics.Conditional(“DEBUG”)]
public static void Test<T> (AssertionCallback<T> callback, T obj, string message)
{
if (callback(obj)) { return; }
throw new AssertionException(“Assertion failed: ‘” + message);
}
#endregion
#region Nested Classes
public delegate bool AssertionCallback ();
public delegate bool AssertionCallback<T> (T obj);
public class AssertionException : ApplicationException
{
public AssertionException (string s) : base(s) { }
}
#endregion
}{/syntaxhighlighter}
The class exposes various Test methods that either accept a boolean expression or a method delegate that returns a boolean value. Then depending upon the value, an AssertionException is thrown if the boolean value evaluates to false.
Moreover, all the Test methods have been decoarted with the System.Diagnostics.Conditional attribute. This attribute ensures that a method and calls to it are only preserved in the compiled code if a particular flag was set during the compilation process. In the above code, I have chosen DEBUG as the flag, which means that calls to the Test methods only execute when the project is being debugged.
The above class works for both Desktop as well as ASP.NET web applications. For web applications, just ensure that you have degug=”true” in the app’s web.config file during development.
You can easily change the flag above if you want to fire Assertions on some custom flag.
Here’s an example of how I used this Assert class to ensure that a condition is always met:
{syntaxhighlighter brush: csharp;fontsize: 100; first-line: 1; }//Assertion – resources should have only unique members.
Assert.Test(delegate()
{
int count=resources.GroupBy(r => r.physicalPath).Count();
return (count == resources.Count);
});{/syntaxhighlighter}
In this particular example, I wanted to ensure that all elements of a Collection were always unique. The Assert class allowed me to neatly test this during development, wihout causing any overhead for production code.
Recent Comments