Wednesday, 17 August 2011

Unit Testing C# Custom Attributes with NUnit Part 4

In Unit Testing C# Custom Attributes with NUnit Part 3 towards the end I showed the following code
Assert.That(MethodBase.GetCurrentMethod(), 
            Has.Attribute<FunkyAttribute>().Property("SettingOne").TypeOf<int>());
to test the type of a property on an attribute.  As it turns out this does not actually do that.  Instead it tests the type of the value returned from the property.  What's happening is that the object returned from Property() isn't some of meta-object representing a property but is the actual value of the property.

In the case above it amounts to the same thing.  As the property type is an int even if it has not been set the value will be 0 of which type is int.  However, if it's a reference type (quite likely a string) or a nullable type the value can be null.  E.g.

Assert.That(MethodBase.GetCurrentMethod(), 
     Has.Attribute<FunkyAttribute>().Property("FunkyName").TypeOf<string>());

 
Which causes the following when run:

AttrTestV3.FunkyTester.TestThatTheTypeOfFunkyNameWhenNotSetIs_string:
  Expected: attribute AttrTestDefs.FunkyAttribute property FunkyName <System.String>
  But was:  <AttrTestDefs.FunkyAttribute>

It seems that when there is no value Property() which tests for the presence of a the specified property name and implicitly returns the value of the property (if found) has nothing to return so for some reason the attribute type obtained from the call Has.Attribute() is returned.

Currently, there is no way with NUnit to handle this case.  I started a thread on the NUnit discussion group which discusses this issue and it seems like the authors of NUnit have some plans.

As an interim solution if the property is optional for a custom attribute then in the fixture make sure a value is assigned.  In the case above:

[Test]
[Funky(FunkyName = "dummy")]
public void TestThatTheTypeOfFunkyNameWhenNotSetIs2_string()
{
    Assert.That(MethodBase.GetCurrentMethod(),
         Has.Attribute<FunkyAttribute>().Property("FunkyName").TypeOf<string>());
}

I think that's the end again:-)  Here are the links to the previous parts: One, two & three.

No comments: