【问题标题】:How to unit test ModelBind with Data Annotation validation?如何使用数据注释验证对 ModelBind 进行单元测试?
【发布时间】:2009-11-03 04:29:57
【问题描述】:

我正在使用 mvc2 框架开发 asp.net mvc 应用程序。

这是视图。

<% using (Ajax.BeginForm("CreateMenuCategory",
           "Admin", 
           new AjaxOptions { UpdateTargetId = "tabs-MenuCategories", }))
       { %>
       <fieldset class="fields">
           <legend>
                Add Menu Categories
            </legend>
            <p>
                <label for="MenuCategoryName">MenuCategory Name:</label>
                <%= Html.TextBox("MenuCategoryName")%>
                <%= Html.ValidationMessage("MenuCategoryName")%>
            </p>
            <p>
                <label for="Description">Description</label>
                <%= Html.TextBox("Description")%>
                 <%= Html.ValidationMessage("Description")%>
            </p>               
            <p>
                <label for="Notes">Notes</label>
                <%= Html.TextBox("Notes")%>
            </p>        
             <p class="submit">
                    <input type="submit" value="Create" />
             </p>       
    </fieldset>
    <% } %>

这是我用于模型绑定的类

public class MenuCategoryBusinessObject
    {


        //private readonly IMenuRepository _repository;
        public int ID { get; set; }

        [Required]
        [StringLength(20)]
        public string MenuCategoryName { get; set; }

        [Required]
        [StringLength(20)]
        public string Description { get; set; }

        public string Notes { get; set; }

        public IEnumerable<MenuItemBusinessObject> MenuItems
        {
            get; set;
        }

    }

这是我的控制

 [HttpPost]
    public ActionResult CreateMenuCategory([Bind(Exclude = "ID")]MenuCategoryBusinessObject  menuCategory)
    {

        if(ModelState.IsValid)
        {//if I am valid.
            _repository.CreateMenuCategory(menuCategory);
        }

        IndexMenuCategory model = new IndexMenuCategory
        {
            MenuCategories = _repository.GetMenuCategories(),
            SelectedMenuCategory = null

        };
        return PartialView("MenuCategories", model);
    }

当我做模型绑定的时候,数据注解验证已经知道模型无效,ModelState.IsValid 为假。

但是,当我进行单元测试时,如果我将自己的 MenuCategoryBusinessObject 输入到 action 方法中,它会绕过模型绑定,并且不会知道 ModelState 无效。

 [Fact]
    public void CreateNewMenuCategory()
    {
        // Setup
        DataStore dataStore = new DataStore();
        IMenuRepository menuRepository = new MenuRepository(dataStore);
        MenuCategoryBusinessObject menuCategoryBusinessObject =
            new MenuCategoryBusinessObject();
        AdminController adminControl = new AdminController(menuRepository);
        adminControl.SetFakeControllerContext();
        adminControl.Request.SetHttpMethodResult("POST");

        // Execute
        adminControl.CreateMenuCategory(menuCategoryBusinessObject);
    }

那么,我的问题是,在这种情况下如何有效地进行单元测试?

【问题讨论】:

    标签: asp.net-mvc unit-testing asp.net-mvc-2


    【解决方案1】:
    controllerInstance.ModelState.AddModelError("", "Dummy value.");
    

    在调用方法之前添加一个虚拟值将清除 IsValid 标志。然后只需调用您的操作方法来测试这个特定的代码路径。

    【讨论】:

      【解决方案2】:

      为了测试模型是否正确注释了数据,我可能会在以下几行中做一些事情:

      [TestMethod]
      public void Description_Should_Be_Required()
      {
          Expression<Func<MenuCategoryBusinessObject, object>> expression = 
              o => o.Description;
          var me = expression.Body as MemberExpression;
          var att = (RequiredAttribute[])me.Member
                    .GetCustomAttributes(typeof(RequiredAttribute), false);
          att.Length.ShouldEqual(1);
      }
      

      您需要测试的另一件事是您有效地使用DataAnnotationsModelBinder 而不是默认的:

      ModelBinders.Binders.DefaultBinder = new DataAnnotationsModelBinder();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-24
        • 2017-09-13
        相关资源
        最近更新 更多