2011-01-12 91 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