2013-09-28 11 views
5

TryValidateObject nie działa z atrybutem walidacji modelu Compare podczas testowania urządzenia.Testowanie jednostki Mvc.Compare Atrybut nieprawidłowo zwraca model isValid = true

Otrzymuję ModelState.IsValid = true, gdy wiem, że jest false (gdy testowanie urządzenia).

Mam ten przykładowy model:

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

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

Korzystając z tej metody pomocnika do walidacji modeli podczas testów jednostkowych:

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

I uruchomić ten test Jednostka:

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

Odpowiedz

2

Obiekt CompareAttribute nie wypełnia właściwości klasy ValidationResult o klasie MemberNames (patrz source). Twój result.MemberNames będzie pusty.

Bo to nie jest wymagane do korzystania z własności (ValidationResult ma nawet constructor do tego) MemberNames więc trzeba zmienić ValidateModel pomocnika do czynienia z tego rodzaju 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); 
} 
Powiązane problemy