【发布时间】:2008-10-23 10:03:44
【问题描述】:
我一直在尝试为 ASP.NET MVC 中的 UserViewControl 编写单元测试。我想编写如下所示的代码:
[TestMethod]
public void HaveControlToDisplayThings()
{
var listControl = new ControlUnderTest();
var viewData = new ViewDataDictionary<IList<string>>(this.repo.GetMeSomeData());
// Set up a ViewContext using Moq.
listControl.SetFakeViewContext(viewData);
listControl.ViewData = viewData;
listControl.RenderView(listControl.ViewContext);
// Never got this far, no idea if this will work :)
string s = listControl.ViewContext.HttpContext.Response.Output.ToString();
Assert.AreNotEqual(0, s.Length);
foreach (var item in this.repo.GetMeSomeData())
{
Assert.IsTrue(s.IndexOf(item) != -1);
}
}
不幸的是,无论我尝试什么,我都会从 RenderView 深处得到错误。这是由静态 HttpContext.Current 对象无用引起的(据我所知) - 我从 System.Web.UI.Page.SetIntrinsics 得到 NullReferenceExceptions。
我尝试使用 Phil Haack 的 HttpSimulator,它给了我一个 HttpContext 对象,但我发现我还需要指定一个假的 HttpBrowserCapabilities 对象才能稍微进一步:
Subtext.TestLibrary.HttpSimulator simulator = new HttpSimulator();
simulator.SimulateRequest();
var browserMock = new Mock<HttpBrowserCapabilities>();
browserMock.Expect(b => b.PreferredRenderingMime).Returns("text/html");
browserMock.Expect(b => b.PreferredResponseEncoding).Returns("UTF-8");
browserMock.Expect(b => b.PreferredRequestEncoding).Returns("UTF-8");
HttpContext.Current.Request.Browser = browserMock.Object;
现在我得到了对该对象的属性访问异常。我尽可能多地嘲笑,但似乎无处可去。
有人设法完成这项工作吗?
【问题讨论】:
-
我很久以前就放弃了对视图的单元测试。尝试将您拥有的任何业务逻辑移动到控制器中,然后对它们进行单元测试。视图对于单元测试来说是出了名的复杂。可能会有一个真正的答案,但我不久前就放弃了,因为我们的观点发展得太快了。
-
是的,一般来说我不想测试我的视图,但是当我使用用户控件时,这是一个可重复使用的部分,经常在整个应用程序中使用并且没有控制器代码可以说。我想测试它是否可以被实例化和渲染并且包含大致正确的东西。
-
据我了解,您实际上是在测试 repo.GetMeSomeData() ,它不依赖于视图或用户控制。你能检查一下 repo.GetMeSomeData() 是否给了你想要的东西而不是调用控件吗?
-
嗨,我知道 GetMeSomeData 正在工作,因为它是独立测试的,我要测试的是来自该调用的数据是否在 HTML 中呈现。
标签: c# asp.net-mvc mocking