Recently I wanted to create some unit tests for the DataAnnotations on my domain model. After a bit of googling I found the following article on testing validation attributes which gave me a good start.

[Fact]
public void NameHasRequiredAttributeWithErrorMessage()  
{
  var type = typeof(Country);
  var methodinfo = type.GetProperty("Name");

  Assert.True(Attribute.IsDefined(methodinfo, typeof(RequiredAttribute)));
}

It works like a charm but after a few tests I got fed up violating DRY and I don’t like the magic string used for the property name, it’s not refactor friendly. so I created a method to refactor the tests down to one line.

[Fact]
public void NameHasRequiredAttribute()  
{
AssertDataAnnotation<Country>.ContainsAttribute<RequiredAttribute, string>(x => x.Name);  
}
public class AssertDataAnnotation<TType> : Assert where TType : class  
{
  public static void ContainsAttribute<TValidationAttribute, TProp>
(Expression<Func>TType, TProp>> expression)
where TValidationAttribute : ValidationAttribute  
  {
    var memberExpression = expression.Body as MemberExpression;
    if (memberExpression == null)
      throw new MissingMemberException("Property is invalid");

    var member = memberExpression.Member;
    if (member.MemberType != MemberTypes.Property)
      throw new MissingMemberException(member.DeclaringType.Name, member.Name);

    True(Attribute.IsDefined(member, typeof(TValidationAttribute)));
  }
}

It could still use some improvements though in the form of type inference to let the compiler work out the property type rather than having to pass it in but I haven’t figured that out yet. Overall it’s pretty useful though.

I’ll look at extending the AssertDataAnnotation class above to validate ErrorMessages and perhaps how to test properties of the ValidationAttribute types passed in next I think.