微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc – 如何使用UpdateModel进行单元测试操作而不进行模拟?

我一直在努力通过Scott Guthrie在 ASP.NET MVC Beta 1的优秀帖子.在其中他展示了对UpdateModel方法的改进以及它们如何改进单元测试.我已经重新创建了一个类似的项目,但是当我运行包含对UpdateModel的调用的UnitTest时,我会收到一个名为controllerContext参数的ArgumentNullException.

这是相关的位,从我的模型开始:

public class Country {
  public Int32 ID { get; set; }
  public String Name { get; set; }
  public String Iso3166 { get; set; }
}

控制器动作:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Int32 id,FormCollection form)
{
  using ( ModelBindingDataContext db = new ModelBindingDataContext() ) {
    Country country = db.Countries.Where(c => c.CountryID == id).SingleOrDefault();

    try {
      UpdateModel(country,form);

      db.SubmitChanges();

      return RedirectToAction("Index");
    }
    catch {
      return View(country);
    }
  }
}

最后我的单元测试失败了:

[TestMethod]
public void Edit()
{
  CountryController controller = new CountryController();
  FormCollection form = new FormCollection();
  form.Add("Name","Canada");
  form.Add("Iso3166","CA");

  var result = controller.Edit(2 /*Canada*/,form) as RedirectToRouteResult;

  Assert.IsNotNull(result,"Expected to be redirected on successful POST.");
  Assert.AreEqual("Show",result.RouteName,"Expected to redirect to the View action.");
}

调用UpdateModel时抛出ArgumentNullException,消息“Value not not null.参数名称:controllerContext”.我假设某个地方UpdateModel需要System.Web.Mvc.ControllerContext,它在执行测试期间不存在.

我也假设我在某处做错了,只需指向正确的方向.

请帮忙!

解决方法

我不认为可以这样做,因为UpdateModel使用的TryUpdateModel引用了ControllerContext,当从单元测试调用时它是null.我使用RhinoMocks来模拟或存根控制器所需的各种组件.
var routeData = new RouteData();
var httpContext = MockRepository.GenerateStub<HttpContextBase>();
FormCollection formParameters = new FormCollection();

EventController controller = new EventController();
ControllerContext controllerContext = 
    MockRepository.GenerateStub<ControllerContext>( httpContext,routeData,controller );
controller.ControllerContext = controllerContext;

ViewResult result = controller.Create( formParameters ) as ViewResult;

Assert.AreEqual( "Event",result.Values["controller"] );
Assert.AreEqual( "Show",result.Values["action"] );
Assert.AreEqual( 0,result.Values["id"] );

以下是www.codeplex.com/aspnet上Controller.cs源代码中的相关位:

protected internal bool TryUpdateModel<TModel>( ... ) where TModel : class
{

     ....

    ModelBindingContext bindingContext =
           new ModelBindingContext( ControllerContext,valueProvider,typeof(TModel),prefix,() => model,ModelState,propertyFilter );

     ...
}

原文地址:https://www.jb51.cc/aspnet/248130.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐