如何在不使用 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 can not”参数名称:controllerContext”。 我假设 UpdateModel
的某个地方需要 System.Web.Mvc.ControllerContext
,但在测试执行期间不存在。
我还假设我在某个地方做错了事情,只需要指出正确的方向。
请帮助!
I have been working my way through Scott Guthrie's excellent post on ASP.NET MVC Beta 1. In it he shows the improvements made to the UpdateModel method and how they improve unit testing. I have recreated a similar project however anytime I run a UnitTest that contains a call to UpdateModel I receive an ArgumentNullException naming the controllerContext parameter.
Here's the relevant bits, starting with my model:
public class Country {
public Int32 ID { get; set; }
public String Name { get; set; }
public String Iso3166 { get; set; }
}
The controller action:
[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);
}
}
}
And finally my unit test that's failing:
[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.");
}
ArgumentNullException
is thrown by the call to UpdateModel
with the message "Value cannot be null. Parameter name: controllerContext". I'm assuming that somewhere the UpdateModel
requires the System.Web.Mvc.ControllerContext
which isn't present during execution of the test.
I'm also assuming that I'm doing something wrong somewhere and just need to pointed in the right direction.
Help Please!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为这是不可能的,因为 UpdateModel 使用的 TryUpdateModel 引用了从单元测试调用时为 null 的 ControllerContext。 我使用 RhinoMocks 来模拟或存根控制器所需的各种组件。
以下是 www.codeplex.com/aspnet 上的 Controller.cs 源代码中的相关部分:
I don't think it can be done since TryUpdateModel, which UpdateModel uses, references the ControllerContext which is null when invoked from a unit test. I use RhinoMocks to mock or stub the various components needed by the controller.
Here's the relevant bit from the Controller.cs source on www.codeplex.com/aspnet:
我也遇到了同样的问题。 在阅读了 tvanfosson 的解决方案后,我尝试了一个不涉及模拟框架的简单解决方案。
将默认的 ControllerContext 添加到控制器,如下所示:
这在单元测试时消除了对我来说很好的错误。 我希望这可以帮助其他人。
I was having this same issue. After reading tvanfosson's solution, I tried a simple solution not involving a mock framework.
Add a default ControllerContext to the controller as follows:
This removed the error just fine for me while unit testing. I hope this may help someone else out.
或者您可以创建表单数据代理,例如
所以 Controller.Action 应该看起来像
Or you can create form data proxy, like
So Controller.Action should look, like