2013-09-28 4 views
5

TryValidateObject scheint nicht mit dem Modellvalidierungsattribut Compare beim Komponententest zu arbeiten.Komponententest Mvc.Compare-Attribut gibt das Modell falsch zurück isValid = true

Ich bekomme ModelState.IsValid = true, wenn ich weiß, es ist false (wenn Unit-Tests).

Ich habe dieses Beispiel Modell bekam:

public class CompareTestModel 
{ 
    public string Password { get; set; } 

    [System.Web.Mvc.Compare(
     "Password", 
      ErrorMessage = "The passwords do not match")] 
    public string PasswordCompare { get; set; } 
} 

diese Hilfsmethode unter Verwendung von Modellen zu validieren, wenn Unit-Tests:

using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Web.Mvc; 

public static class ModelHelper 
{ 
    public static void ValidateModel(
     this Controller controller, 
     object viewModel) 
    { 
     controller.ModelState.Clear(); 

     var validationContext = new ValidationContext(viewModel, null, null); 
     var validationResults = new List<ValidationResult>(); 

     Validator.TryValidateObject(
      viewModel, 
      validationContext, 
      validationResults, 
      true); 

     foreach (var result in validationResults) 
     { 
      foreach (var name in result.MemberNames) 
      { 
       controller.ModelState.AddModelError(name, result.ErrorMessage); 
      } 
     } 
    } 
} 

Und ich dieses Gerät Test ausführen:

[Test] 
    public void CompareAttributeTest() 
    { 
     // arrange 
     var model = new CompareTestModel(); 
     model.Password = "password"; 
     model.PasswordCompare = "different password"; 

     AccountController controller = new AccountController(); 

     // act 
     controller.ValidateModel(model); 

     // assert 
     Assert.IsFalse(controller.ModelState.IsValid); 
    } 

Antwort

2

Die CompareAttribute füllt nicht die ValidationResult Klasse MemberNames Eigenschaft (siehe source). So wird Ihre result.MemberNames leer sein.

Da ist es nicht zu verwenden, um die MemberNames Eigenschaft erforderlich (die ValidationResult sogar ein constructor dafür hat), so müssen Sie Ihren ValidateModel Helfer ändern, um mit dieser Art von ValidationResult beschäftigen:

foreach (var result in validationResults) 
{ 
    if (result.MemberNames.Any()) 
    { 
     foreach (var name in result.MemberNames) 
     { 
      controller.ModelState.AddModelError(name, result.ErrorMessage); 
     } 
    } 
    else 
     controller.ModelState.AddModelError("", result.ErrorMessage); 
} 
Verwandte Themen