哪种模型绑定方法在ASP.NET MVC中具有最佳单元测试语义?

Cra*_*ntz 5 asp.net-mvc unit-testing modelbinders

定义

在ASP.NET MVC中,有两种方法可以在操作中进行模型绑定.我们称之为"绑定参数方式"和"UpdateModel方式".它们两者几乎完全相同,它们以几乎完全相同的方式完成:

    public ActionResult UpdateWithBindArguments(Foo model)
    {
        Repository.Update(model);
        // error handling removed
        return RedirectToAction(...)
    }

    public ActionResult UpdateWithUpdateModel()
    {
        Foo model; 
        UpdateModel(model); // part of MVC framework
        Repository.Update(model);
        // error handling removed
        return RedirectToAction(...)
    }
Run Code Online (Sandbox Code Playgroud)

正如我所说,这些几乎完全相同.第一个可能稍微更具可读性,但我可以克服它.

两种测试方法

重要的区别,我想,就是怎么你单位对其进行测试:

    [TestMethod]
    public void TestUpdateWithBindArguments()
    {
       var model = new Foo() { PropertyName = "Bar" };
       var controller = new FooController();

       var result = controller.UpdateWithBindArguments(model);

       // assert
    }

    [TestMethod]
    public void TestUpdateWithUpdateModel()
    {
       var formData = new FormCollection() { { "PropertyName", "Bar" } };
       var controller = new FooController();
       controller.ValueProvider = formData.ToValueProvider();

       var result = controller.UpdateWithUpdateModel();

       // assert
    }
Run Code Online (Sandbox Code Playgroud)

第一种方法使用强大的静态类型构建模型.第二个构造提交了具有名称/值对的用户数据.我发现第一种方法更容易阅读,但第二种方法更接近于网站调用控制器时实际发生的情况.

由于远远超出了本问题范围的原因,我从来没有说过应该使用lambda表达式而不是字符串来构建用于模型绑定的aspx页面.我很乐意与你进行讨论,但我们不要在这里做.出于这个问题的目的,让我们理所当然地认为我将使用内置的HtmlHelper方法,这些方法采用字符串而不是对其进行扩展,这些方法采用lambda表达式.因此,第二种方法使用名称/值对作为针对aspx页面的"动态"性质的非正式测试具有一定的价值.当然,它不会取代针对该站点的集成测试.

问题(最后!)

我看到两种方法的优点和缺点.我的问题是,是否有一个非常强烈的论据支持我遗漏的一种方法?

编辑我正在寻找客观答案.我正在寻找一个非明显的原因,为什么一种方法比另一种方法更好,而不是试图进行民意调查.

Haa*_*ked 3

在测试方面,在我看来,将对象直接传递给操作方法更自然。无需填充 ValueProviderDictionary。

需要其他方法的原因是您可能需要控制要绑定的对象的实例化。DefaultModelBinder 只是查找默认构造函数并调用它。

但在某些情况下,您可能需要自己创建对象,然后再将其绑定到表单值。这就是 UpdateModel 发挥作用的地方。