I was going through http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html, in this post I didn't like the idea of putting the validation tests in controller test and somewhat manual checking in each test that if the validation attribute exists or not. So, below is the helper method and it's usage which I implemented, it works for both EDM (which has metadata attributes, because of the reason we can not apply attributes on auto generated EDM classes) and POCO objects which have ValidationAttributes applied to their properties.
The helper method does not parse into hierarchical objects, but validation can be tested on flat individual objects(Type-level)
class TestsHelper
{
internal static void ValidateObject<T>(T obj)
{
var type = typeof(T);
var meta = type.GetCustomAttributes(false).OfType<MetadataTypeAttribute>().FirstOrDefault();
if (meta != null)
{
type = meta.MetadataClassType;
}
var propertyInfo = type.GetProperties();
foreach (var info in propertyInfo)
{
var attributes = info.GetCustomAttributes(false).OfType<ValidationAttribute>();
foreach (var attribute in attributes)
{
var objPropInfo = obj.GetType().GetProperty(info.Name);
attribute.Validate(objPropInfo.GetValue(obj, null), info.Name);
}
}
}
}
/// <summary>
/// Link EDM class with meta data class
/// </summary>
[MetadataType(typeof(ServiceMetadata))]
public partial class Service
{
}
/// <summary>
/// Meta data class to hold validation attributes for each property
/// </summary>
public class ServiceMetadata
{
/// <summary>
/// Name
/// </summary>
[Required]
[StringLength(1000)]
public object Name { get; set; }
/// <summary>
/// Description
/// </summary>
[Required]
[StringLength(2000)]
public object Description { get; set; }
}
[TestFixture]
public class ServiceModelTests
{
[Test]
[ExpectedException(typeof(ValidationException), ExpectedMessage = "The Name field is required.")]
public void Name_Not_Present()
{
var serv = new Service{Name ="", Description="Test"};
TestsHelper.ValidateObject(serv);
}
[Test]
[ExpectedException(typeof(ValidationException), ExpectedMessage = "The Description field is required.")]
public void Description_Not_Present()
{
var serv = new Service { Name = "Test", Description = string.Empty};
TestsHelper.ValidateObject(serv);
}
}
this is another post http://johan.driessen.se/archive/2009/11/18/testing-dataannotation-based-validation-in-asp.net-mvc.aspx which talks about validating in .Net 4, but i think i am going to stick to my helper method which is valid in both 3.5 and 4