2011-01-12 64 views
26

我有一个自定义的asp.net mvc类验证属性。 我的问题是如何单元测试它? 测试该类具有该属性是一回事,但这实际上并不会测试其中的逻辑。这是我想测试的。如何单元测试我的自定义验证属性

[Serializable] 
[EligabilityStudentDebtsAttribute(ErrorMessage = "You must answer yes or no to all questions")] 
public class Eligability 
{ 
    [BooleanRequiredToBeTrue(ErrorMessage = "You must agree to the statements listed")] 
    public bool StatementAgree { get; set; } 

    [Required(ErrorMessage = "Please choose an option")] 
    public bool? Income { get; set; } 

.....为了简洁 }

[AttributeUsage(AttributeTargets.Class)] 
public class EligabilityStudentDebtsAttribute : ValidationAttribute 
{ 
    // If AnyDebts is true then 
    // StudentDebts must be true or false 

    public override bool IsValid(object value) 
    { 
     Eligability elig = (Eligability)value; 
     bool ok = true; 
     if (elig.AnyDebts == true) 
     { 
      if (elig.StudentDebts == null) 
      { 
       ok = false; 
      } 
     } 
     return ok; 

    } 
} 

我曾尝试如下编写测试,但这不起作用删除:

[TestMethod] 
public void Eligability_model_StudentDebts_is_required_if_AnyDebts_is_true() 
{ 

    // Arrange 
    var eligability = new Eligability(); 
    var controller = new ApplicationController(); 

    // Act 
    controller.ModelState.Clear(); 
    controller.ValidateModel(eligability); 
    var actionResult = controller.Section2(eligability,null,string.Empty); 

    // Assert 
    Assert.IsInstanceOfType(actionResult, typeof(ViewResult)); 
    Assert.AreEqual(string.Empty, ((ViewResult)actionResult).ViewName); 
    Assert.AreEqual(eligability, ((ViewResult)actionResult).ViewData.Model); 
    Assert.IsFalse(((ViewResult)actionResult).ViewData.ModelState.IsValid); 
} 

ModelStateDictionary不包含此自定义属性的关键字。 它只包含标准验证属性的属性。

这是为什么?

什么是测试这些自定义属性的最佳方式?

回答

35

你的属性EligabilityStudentDebtsAttribute只是一个标准的类,就像其他的一样,只是单元测试IsValid()方法。如果它工作正常,信任框架该属性工作正常。

所以:

[Test] 
public void AttibuteTest() 
{ 
    // arrange 
    var value = //.. value to test - new Eligability() ; 
    var attrib = new EligabilityStudentDebtsAttribute(); 

    // act 
    var result = attrib.IsValid(value); 

    // assert 
    Assert.That(result, Is.True) 
} 
+0

Doh!当然! – MightyAtom

+1

这是做交叉属性验证的最佳方式吗? (涉及多个属性的模型验证) – MightyAtom

+0

保持简单..尝试,如果对你有用 - 没有理由进行更多的测试:) –

6

您的自定义验证属性可能依赖于其他属性的状态。在这种情况下,您可以使用静态方法System.ComponentModel.DataAnnotations.Validator,例如:

var model = ... 
var context = new ValidationContext(model); 
var results = new List<ValidationResult>(); 
var isValid = Validator.TryValidateObject(model, context, results, true); 
Assert.True(isValid); 
+1

你可能需要添加true标志来验证所有属性 - “Validator.TryValidateObject(model,context,results,true);” - 在使用NUnit测试我的验证时出现问题,“受保护的覆盖ValidationResult IsValid(..)”内部的验证没有受到影响,除非我提供的“validateAllProperties”为true - 因此测试没有按预期运行,我也无法运行调试到我的代码。 – JimiSweden