我该如何测试MVC UserViewControl?

我该如何测试MVC UserViewControl?

问题描述:

我一直在尝试一段时间来为ASP.NET MVC中的UserViewControl编写单元测试。我希望得到的代码看起来是这样的:我该如何测试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得到NullReferenceException

我试着用菲尔哈克的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; 

现在,我得到的财产异常访问该对象。我尽可能多地嘲笑,但似乎没有什么快。

有没有人设法使这项工作?

+0

很久以前,我放弃了单元测试视图。尝试将您拥有的任何业务逻辑移入控制器,然后单元测试。单元测试的观点非常复杂。 可能有一个真实的答案,但我放弃了它,因为我们的观点发展太快。 – CVertex 2008-10-24 05:58:28

+0

是的,一般来说,我不想测试我的观点,但是当我使用用户控件时,这是一个可重复使用的部分,经常在应用程序中使用,并且没有控制器代码。我想测试它可以被实例化和渲染,并且包含大致正确的东西。 – 2008-10-27 12:24:28

+0

据我所知,你实际上正在测试repo.GetMeSomeData(),它不依赖于视图或用户控件。你能否检查一下repo.GetMeSomeData()是否给你你想要的而不是调用控件? – Graviton 2009-01-01 10:01:09

不幸的是,ASP.NET viewengine在ASP.NET宿主环境中使用了VirtualPathProvider。更糟糕的是,我使用Reflector追踪了其他一些代码,并发现对于某些到VirtualPath实用程序的硬编码引用还存在其他依赖关系。 我希望他们在发布中解决这个问题,以便我们真正能够测试视图以及它们如何呈现。

一种选择是在浏览器内运行单元测试。对于这种情况,我已成功应用Selenium

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

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

这些是需要在HttpBrowserCapabilities对象中设置的值,以便运行一个asp.net webforms站点,我会尝试确保这些值已设置,看看是否可以修复您的问题,我不确定它是否会但是,嘿它值得一拍吗?

  • 浏览器(也称为名称)
  • 用户代理(在请求中传递)
  • 表(真/假)
  • 版本
  • w3cdomversion(例如1.0)
  • (浏览器例如1.0版本)
  • 饼干(真/假)
  • ecmascriptversion(例如1.0)

希望这会有所帮助。

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

这里是一个guide用于集成Selenium和你的CC.Net。

使用TypeMock来嘲笑依赖关系。我已经写了one blog post关于如何模拟Controller层中的请求和响应依赖关系。也许这有帮助。