单元测试MetadataType

时间:2010-11-01 11:55:49

标签: c# asp.net unit-testing asp.net-mvc-2 asp.net-mvc-2-metadata

我正在研究ASP.NET MVC 2应用程序,我测试我的Viewmodels就像这样

[TestMethod]
public void EmailNeedsToBeSet()
{
    var pvm = new ProfileViewModel {Email = ""};
    var validationResults = new ValidationResults();
    var result = Validator.TryValidateObject(pvm, new ValidationContext(pvm, null, null), validationResults, true);
    Assert.IsFalse(result);
    Assert.IsTrue(validationResults.ContainsField<ProfileViewModel>(m => m.Email));
}

电子邮件属性是必需的,此测试方法正常

我的问题现在是:我如何在之前的测试中测试MetaData类?验证结果始终为真。或者这不可能吗?

我的MetaData-Class示例:

[MetadataType(typeof (UserMetaData))]
public partial class User
{
   public class UserMetaData
   {
      [Required(ErrorMessageResourceName = "Required",
      ErrorMessageResourceType = typeof (ValidationStrings))]
      [LocalizedDisplayName("LoginName", NameResourceType = typeof (Fields))]
      [StringLength(64)]
      public string Login { get; set; }
   }
}

1 个答案:

答案 0 :(得分:2)

以下是我对这类代码进行单元测试的方法:

    [TestMethod]
    public void IsValid_Returns_ValidationResult_Errors_When_Properties_With_Meta_Data_Are_Not_Valid()
    {
        var sut = new User
                      {
                          Login = "too long!!!"
                      };

        var actual = sut.IsValid();

        Assert.IsNotNull(actual);
        Assert.AreEqual(1, actual.Count);
        Assert.AreEqual(1, actual[0].MemberNames.Count());
        var firstValidationError = actual[0];
        Assert.AreEqual("Login", firstValidationError.MemberNames.First());
        Assert.AreEqual("The field Login must be a string with a maximum length of 4.", firstValidationError.ErrorMessage);
    }

    [TestMethod]
    public void IsValid_Returns_Empty_List_Of_Errors_When_Properties_With_Meta_Data_Are_Valid()
    {
        var sut = new User
                      {
                          Login = "abcd"
                      };

        var actual = sut.IsValid();

        Assert.IsNotNull(actual);
        Assert.AreEqual(0, actual.Count);
    }

[MetadataType(typeof(UserMetaData))]
public partial class User : BaseEntity
{
    public string Login { get; set; }

    public class UserMetaData
    {
        [Required]              
        [StringLength(4)]       
        public string Login { get; set; }
    }
}

public abstract class BaseEntity
{
    protected BaseEntity()
    {
        RegisterMetadata();
    }

    private void RegisterMetadata()
    {
        var currentType = GetType();

        var metadataType = GetMetadataType();

        if (metadataType == null)
            return;

        var descriptorProvider = new AssociatedMetadataTypeTypeDescriptionProvider(currentType, metadataType);
        TypeDescriptor.AddProviderTransparent(descriptorProvider, currentType);
    }

    private Type GetMetadataType()
    {
        var attribute = Attribute.GetCustomAttributes(this.GetType()).ToList().Find(t => t is MetadataTypeAttribute);

        return (attribute != null)
                   ? ((MetadataTypeAttribute)attribute).MetadataClassType
                   : null;
    }

    public virtual List<ValidationResult> IsValid()
    {
        var validationErrors = new List<ValidationResult>();
        var context = new ValidationContext(this, null, null);
        Validator.TryValidateObject(this, context, validationErrors, true);

        return validationErrors;
    }
}