Reinventing The Wheel

Assert.IsNotNull() Should Be Constrained

A few days ago I saw some code in the project I'm currently working on. One of my colleagues had written something like this:

int x = GetSomeIntegerValue();
Assert.IsNotNull(x);

The "int" and "NotNull" immediately caught my attention.

I had a think about it, and realised that this will never throw an Exception.

I asked my colleague why he wrote this and he said it was to test that GetSomeIntegerValue() didn't return 0.

I explained to him the following:

  • The parameter in the IsNotNull() method is of type Object.
  • Int is a value type.
  • Any value type will be boxed into an Object when passed to a method that is expecting an Object.
  • A boxed value type can never be null.

He then understood why his test will never fail, and changed it accordingly (side note - always make sure your test can fail as well as pass, otherwise, what's the point of the test?).

This is a perfect example of how important it is to have a good understanding of lower level concepts, such as boxing.

What it should (or rather "could") have been

The full name of the method is:

Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull()

and the method signature is:

public static void IsNotNull(Object value)

I was so intrigued as to why Microsoft didn't constrain the parameter to a reference type using:

public static void IsNotNull<T>(T value) where T : class

So I posted a question on StackOverflow.com

In short, the reason why Microsoft didn't use parameter constraints is because generics didn't exist back in C# 1.0

If they changed it to use generics and paramter constraints, it would have broken code written using C# 1.0.

This is just one of those things you have to live with since it's not the end of the world, and doesn't break old code. As long as you keep yourself educated about what's going on behind the scenes, you'll be right.

Update: Since I wrote this, I've been told the answer is to use Fluent Assertions (fluentassertions.com), I'll have to have a look into this when I get some time.