2013-09-28 3 views
5

TryValidateObject, похоже, не работает с атрибутом проверки модели Compare при модульном тестировании.Тестирование модуля Mvc.Compare Атрибут неверно возвращает модель isValid = true

Я получаю ModelState.IsValid = true, когда знаю, что это false (при модульном тестировании).

Я получил этот пример модель:

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

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

Используя этот вспомогательный метод для проверки моделей, когда модульное тестирование:

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

И я запускаю этот тест блока:

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

ответ

2

CompareAttribute не заполняет ValidationResult класс MemberNames (см. source). Таким образом, ваш result.MemberNames будет пустым.

Потому что не требуется использовать свойство MemberNames (ValidationResult даже имеет constructor для этого), так что вы должны изменить свой ValidateModel помощника, чтобы иметь дело с такого рода 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); 
} 
Смежные вопросы