2013-09-28 10 views
5

TryValidateObject non sembra funzionare con l'attributo di convalida del modello Compare durante il test dell'unità.Test dell'unità L'attributo Mvc.Compare restituisce erroneamente il modello isValid = true

Ottengo ModelState.IsValid = true, quando so che è false (durante il test dell'unità).

Ho questo esempio il modello:

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

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

Usando questo metodo di supporto per validare i modelli quando il test delle unità:

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); 
      } 
     } 
    } 
} 

e corro questo test unità:

[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); 
    } 

risposta

2

Il CompareAttribute non compila la proprietà ValidationResult classe MemberNames (vedere source). Quindi il tuo result.MemberNames sarà vuoto.

Poiché non è necessario per utilizzare la proprietà MemberNames (la ValidationResult ha anche un constructor per questo) quindi è necessario cambiare il vostro ValidateModel aiuto per affrontare questo tipo di ValidationResult:

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); 
} 
Problemi correlati