【发布时间】:2011-12-08 21:39:02
【问题描述】:
我有一个正在尝试进行单元测试的 MVC 3 应用程序。我从this page 中阅读了示例,该示例显示了如何模拟控制器。这是我的测试代码:
[TestMethod]
public void TestAddStudy() {
var controller = new AdminController();
var httpContext = FakeHttpContext();
var context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
controller.ControllerContext = context;
var request = Mock.Get(controller.Request);
request.Setup(r => r.Form).Returns(delegate() {
var nv = new FormCollection();
nv.Add("Name", "Test Study");
nv.Add("IsDefault", "selected");
return nv;
});
var result = controller.CreateStudy(request.Object.Form as FormCollection) as ActionResult;
}
public static HttpContextBase FakeHttpContext() {
var httpContext = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>();
var response = new Mock<HttpResponseBase>();
var session = new Mock<HttpSessionStateBase>();
var server = new Mock<HttpServerUtilityBase>();
httpContext.Setup(ctx => ctx.Request).Returns(request.Object);
httpContext.SetupGet(ctx => ctx.Request.RequestType).Returns("POST");
httpContext.Setup(ctx => ctx.Response).Returns(response.Object);
httpContext.Setup(ctx => ctx.Session).Returns(session.Object);
httpContext.Setup(ctx => ctx.Server).Returns(server.Object);
httpContext.SetupGet(ctx => ctx.User.Identity.Name).Returns("testClient");
return httpContext.Object;
}
这是控制器内部的代码:
[HttpPost]
public ActionResult CreateStudy(FormCollection form) {
Study newStudy = new Study();
TryUpdateModel(newStudy);
newStudy.CreatedBy = CurrentUser;
newStudy.CreatedOn = DateTime.Now;
studyRepository.Edit(newStudy, CurrentUser);
return RedirectToAction("EditStudy", new { id = 1 });
}
每次在 TryUpdateModel 语句上失败,对象引用未设置为对象错误的实例。我做错了什么......或者更重要的是,我怎样才能对这个简单的方法进行单元测试?
堆栈跟踪:
在 Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.CollectionReplacer.GetUnvalidatedCollections(HttpContext 上下文)
在 Microsoft.Web.Infrastructure.DynamicValidationHelper.ValidationUtility.GetUnvalidatedCollections(HttpContext 上下文,Func1& formGetter, Func1& queryStringGetter)
在 System.Web.Helpers.Validation.Unvalidated(HttpRequest 请求)
在 System.Web.Mvc.FormValueProviderFactory.<.ctor>b_0(ControllerContext cc)
在 System.Web.Mvc.FormValueProviderFactory.GetValueProvider(ControllerContext controllerContext)
在 System.Web.Mvc.ValueProviderFactoryCollection.c_DisplayClassc.b__7(ValueProviderFactory 工厂)
在 System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
在 System.Collections.Generic.List1..ctor(IEnumerable1 集合)
在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 源)
在 System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext controllerContext)
在 System.Web.Mvc.ControllerBase.get_ValueProvider()
在 System.Web.Mvc.Controller.TryUpdateModel[TModel](TModel 模型)
在 C:\Visual Studio Projects\Controllers\AdminController.cs:line 254 中的 Controllers.AdminController.CreateStudy(FormCollection form)
在 C:\Visual Studio Projects\Tests\UnitTest1.cs:line 32 中的 Tests.UnitTest1.TestAddStudy() 处
【问题讨论】:
-
请包含堆栈跟踪。
-
我只是想建议你使用 MVC Contrib 的 TestHelper :mvccontrib.codeplex.com/wikipage?title=TestHelper 它会更容易编写测试。
标签: .net asp.net-mvc-3 unit-testing