Как выполнить модульное тестирование DataAnnotationsModelBinder в ASP.NET MVC 2 - PullRequest
3 голосов
/ 21 января 2010

Я использую ASP.NET MVC 2 с атрибутами DataAnnotation, разбросанными по таким свойствам:

public class LogOnViewModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }

    [Required]
    public string Domain { get; set; }
}

У меня есть модульный тест, который проверяет, что текущий вид отображается при сбое проверки. Однако я вручную добавляю ошибки к ModelState, чтобы заставить его работать:

    [Test]
    public void TestThatLogOnActionRedirectsToLogOnViewIfValidationFails()
    {
        //create a invalid view model
        var model = new LogOnViewModel {UserName = "jsmith"};

        //Can I avoid doing this manually?
        //populate Model State Errors Collection
        _accountController.ModelState.AddModelError("FirstName", "First Name Required");
        _accountController.ModelState.AddModelError("LastName", "Last Name Required");

        var result = _accountController.LogOn(model);

        result.AssertViewRendered()
            .ForView(Constants.Views.LogOn)
            .WithViewData<LogOnViewModel>();
    }

Есть ли способ непосредственного или косвенного взаимодействия с ModelBinder в модульном тесте? Например:

    [Test]
    public void TestThatLogOnActionRedirectsToLogOnViewIfValidationFails()
    {
        //create a invalid view model
        var model = new LogOnViewModel {UserName = "jsmith"};

        //validate model
        //not sure about the api call...
        var validationResults = new DataAnnotationsModelBinder().Validate(model);

        _accountController.ModelState.Merge(validationResults);
        var result = _accountController.LogOn(model);

        result.AssertViewRendered()
            .ForView(Constants.Views.LogOn)
            .WithViewData<LogOnViewModel>();
    }

Ответы [ 2 ]

1 голос
/ 22 января 2010

У Брэда Уилсона есть хороший пост в блоге о DataAnnotationsModelBinder, в том числе о том, как его тестировать: http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html

0 голосов
/ 21 июня 2013

Обычно я тестирую настройки проверки модели напрямую, вызывая методы фасада System.ComponentModel.DataAnnotations.Validator.

Я написал статью на эту тему http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/

Я получаю код, подобный этому (в статье показан базовый класс модульных тестов для более чистого и многократного использования для проверки модели)

[Test]
[TestCaseSource("ValidationRule_Source")]
public void ValidationRule(ValidateRuleSpec spec) {
    // Arrange
    var model = CreateValidPersonModel();
    // Apply bad valud
    model.GetType().GetProperty(spec.MemberName).SetValue(model, spec.BadValue);

    // Act
    var validationResults = new List<ValidationResult>();
    var success = Validator.TryValidateObject(model, new ValidationContext(model), validationResults, true);

    // Assert
    Expect(success, False);
    Expect(validationResults.Count, EqualTo(1));
    Expect(validationResults.SingleOrDefault(r => r.MemberNames.Contains(spec.MemberName)), Not.Null);
}

public IEnumerable<ValidateRuleSpec> ValidationRule_Source() {
    yield return new ValidateRuleSpec() {
        BadValue = null,
        MemberName = "FirstName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = string.Empty,
        MemberName = "FirstName"
    };
    yield return new ValidateRuleSpec() {
        BadValue = null,
        MemberName = "LastName"
    };
    /* ... */
}

Мне не нравится, что доверяющий код просто работает, поэтому я систематически пишу модульный тест для кода проверки моей модели. Тем не менее, я доверяю связующему фреймворка / модели для выполнения валидации. Этот модульный тест позволяет мне написать контроллер, который доверяет валидации.

...