views:

42

answers:

2

I have two attributes - MigrationAttribute and TestDataMigrationAttribute : MigrationAttribute. How can I assert that a class has applied TestDataMigrationAttribute but not MigrationAttribute (which is the parent attribute class)?

A: 

If you want to check for TestDataMigrationAttribute, then make sure you specify its explicit type when using Type.GetCustomAttributes():

typeof(MyClass).GetCustomAttributes(typeof(TestDataMigrationAttribute));

GetCustomAttributes returns the attributes that are, or derived from, the specified attribute type. If you use the type of the derived attribute (TestDataMigrationAttribute), you will not find the base attribute (MigrationAttribute). If you use the type of the base attribute, you will find both attributes.

The above example will return an attribute only if [TestDataMigration] is marked on the class, and not if [Migration] is on the class.

If you need to check for the case where both attributes may be defined on the class, but you only want classes that have only [TestDataMigration], then you will have to either check for the base attribute type and analyse the resulting array, or do the check twice - once for each attribute type.

adrianbanks
A: 
  object[] attributes = typeof(MyTestClass).GetCustomAttributes(typeof(MigrationAttribute), true);
  Assert.IsNotNull(attributes);
  Assert.IsTrue(attributes.Any(x => x is TestDataMigrationAttribute));
  Assert.IsFalse(attributes.Any(x => x is MigrationAttribute && !(x is TestDataMigrationAttribute)));

(assuming you can define both attributes on the class)

Rob
Nice use of LINQ and it works, thanks!
Pawel Krakowiak