如何对MVC UserViewControl进行单元测试?

时间:2008-10-23 10:03:44

标签: c# asp.net-mvc mocking

我已经尝试了一段时间为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对象没用 - 这导致(据我所知) - 我从NullReferenceException得到System.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;

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

有没有人设法做到这一点?

6 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

我们还使用Resharper Solution Wide Analysis来检查是否存在编译器错误。不完美,但结果非常相似。下行 - WatiN测试很慢。

答案 3 :(得分:1)

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

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

希望这有帮助。

答案 4 :(得分:1)

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

以下是用于将Selenium与CC.Net集成的guide

答案 5 :(得分:1)

使用TypeMock模拟依赖项。我写了one blog post关于如何模拟Controller层中的请求和响应依赖关系。也许它很有帮助。