Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

default(T) behaviour on anonymous types

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?

like image 545
Moo-Juice Avatar asked Dec 20 '22 06:12

Moo-Juice


1 Answers

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.

like image 195
Sergey Kalinichenko Avatar answered Feb 06 '23 21:02

Sergey Kalinichenko