简体   繁体   English

如何在ASP.NET MVC 2中单元测试DataAnnotationsModelBinder

[英]How to unit test the DataAnnotationsModelBinder in ASP.NET MVC 2

I'm using ASP.NET MVC 2 with DataAnnotation attributes sprinkled on properties like so: 我正在使用带有DataAnnotation属性的ASP.NET MVC 2,如下所示:

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

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

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

I have a unit test which checks that the current view is rendered when validation fails. 我有一个单元测试,它检查验证失败时是否呈现当前视图。 However, I'm manually adding errors to the ModelState to get it to work: 但是,我手动将错误添加到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>();
    }

Is there a way to interact with the ModelBinder either directly or indirectly in a unit test? 有没有办法直接或间接地在单元测试中与ModelBinder交互? For example: 例如:

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

Brad Wilson有一篇关于DataAnnotationsModelBinder的博文,包括如何对其进行单元测试: http//bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html

I usually unit test my model validation setup by directly calling the facade methods of System.ComponentModel.DataAnnotations.Validator. 我通常通过直接调用System.ComponentModel.DataAnnotations.Validator的facade方法来单元测试我的模型验证设置。

I wrote a article on the subject http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/ 我写了一篇关于这个主题的文章http://timoch.com/blog/2013/06/unit-testing-model-validation-with-mvcs-dataannotations/

I end up with code like this (the article show a cleaner and reusable unit test base class for model validation) 我最终得到这样的代码(文章显示了一个更清晰,可重用的单元测试基类,用于模型验证)

[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"
    };
    /* ... */
}

I don't like trusting code to just work so I systematically write unit test for my model validation code. 我不喜欢信任代码只是工作所以我系统地为我的模型验证代码编写单元测试。 However, I do trust the framework/model binder to execute validation. 但是,我确实相信框架/模型绑定器可以执行验证。 This unit test allows me to write controller that trust the validation is OK. 这个单元测试允许我编写信任验证的控制器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM