7

我一直在尝试为 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 对象无用引起的(据我所知) - 我NullReferenceExceptionSystem.Web.UI.Page.SetIntrinsics.

我尝试使用 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;

现在我得到了对该对象的属性访问异常。我尽可能多地嘲笑,但似乎无处可去。

有没有人设法完成这项工作?

4

6 回答 6

3

不幸的是,ASP.NET 视图引擎在 ASP.NET 宿主环境中使用了 VirtualPathProvider。更糟糕的是,我使用 Reflector 跟踪了一些其他代码,发现对 VirtualPath 实用程序的一些硬代码引用存在其他依赖关系。我希望他们在版本中解决这个问题,这样我们就可以真正测试我们的视图以及它们是如何呈现的。

于 2008-12-23T23:37:08.913 回答
2

一种选择是在浏览器中运行单元测试。在这种情况下,我在Selenium上取得了成功。

于 2008-12-23T23:27:09.527 回答
2

我们放弃了单元测试视图,现在使用 WatiN 浏览器测试作为我们构建的一部分。

我们还使用 Resharper 解决方案范围分析来检查是否存在编译器错误。不完美,但它得到了非常相似的结果。缺点 - WatiN 测试很慢。

于 2008-12-23T23:34:32.930 回答
1

这些是需要在 HttpBrowserCapabilities 对象中设置才能运行 asp.net webforms 站点的值,我会尝试确保设置这些值,看看是否能解决您的问题,我不确定是否会,但嘿值得一试吗?

  • 浏览器(又名)
  • useragent(在请求中传递)
  • 表(真/假)
  • 版本(浏览器版本,例如 1.0)
  • w3cdomversion(例如 1.0)
  • 饼干(真/假)
  • ecmascript 版本(例如 1.0)

希望这可以帮助。

于 2008-12-28T22:58:01.610 回答
1

我也会推荐selenium用于 UI 测试。标准 MVC 应用程序中有相当多的内容可以进行单元测试,但 UI 级别的组件似乎更适合 Selenium 等浏览器内测试。您可以使用Cruisecontrol.net将 Selenium 测试与您的单元测试集成。

这是将 Selenium 与 CC.Net 集成的指南

于 2008-12-30T15:50:42.580 回答
1

使用 TypeMock 来模拟依赖项。我写了一篇关于如何在控制器层模拟请求和响应依赖项的博客文章。也许它有帮助。

于 2008-12-30T15:55:20.277 回答