I'm in the process of writing unit tests against our core framework, and came across this.
We have an extension method that looks like this:
public static T ThrowIfDefault<T>(this T self, string variableName)
{
if (self.Equals(default(T)))
throw new ArgumentException(string.Format("'{0}' cannot be default(T)", variableName));
return self;
} // eo ThrowIfDefault<T>
(A variation on a ThrowIfNull<>
extension method I saw here on Stack Overflow.
In writing a test case for this, I first wrote a helper:
public void ThrowIfDefaultTestHelper<T>(T value)
{
// unit test *itself* requires that a value be specified!!
Assert.AreNotEqual(default(T), value);
// Good test
GenericExtensionMethods.ThrowIfDefault(value, "value");
// Bad test
try
{
GenericExtensionMethods.ThrowIfDefault(default(T), "value");
}
catch (ArgumentException)
{
// Expected result
}
catch (Exception)
{
throw;
}
}
And then the following:
[TestMethod()]
public void ThrowIfDefaultTest()
{
ThrowIfDefaultTestHelper<int>(10);
ThrowIfDefaultTestHelper<Guid>(Guid.NewGuid());
ThrowIfDefaultTestHelper<DateTime>(DateTime.Now);
ThrowIfDefaultTestHelper<object>(new { Name = "Test" }); // anonymous object
}
The Unit test fails on the last one as a NullReferenceException
is thrown, because I am guessing object
has no default(T)
(or does it?). Can I not test anonymous objects this way?
object
does have default(T)
, it just happens to be null
. This is unlike your other test cases that use non-nullable value types. That's why you get a NullReferenceException
instead of the one that you expect.
If you replace
self.Equals(default(T))
with
EqualityComparer<T>.Default.Equals(obj, default(T))
you should start getting the expected ArgumentException
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With