如果可以构造,为什么要模拟HttpContext?

时间:2009-11-06 10:38:08

标签: asp.net asp.net-mvc testing mocking httpcontext

我总是在ASP.NET中伪装/嘲笑/存储HttpContext(在ASP.NET MVC / MonoRail中更容易)。

但是我可以看到HttpContext本身可以很容易地构造,字面上只有几行代码。

var tw = new StringWriter();
var workerReq = new SimpleWorkerRequest("/webapp", @"c:\here\there\wwwroot", "page.aspx", tw);
var context = new HtpContext(workerReq);

如果我们将这段代码包装成这样的东西它应该可以正常工作,我们甚至可以使用它来渲染ASPX:

using(Simulate.HttpContext()) {
  HttpContext.Current.BlaBla;
}

所以问题是:

  1. 不应该这样做的原因。
  2. 应该这样做的原因。
  3. 为什么它没有被广泛使用(事实上我不记得有关它的任何帖子)。
  4. 我记得Phill Haack使用Reflection hacks构建HttpContext的帖子 但它似乎并不需要。

    干杯,
    德米特里。

3 个答案:

答案 0 :(得分:5)

进行非常简单的测试很好,但是如何对使用HttpRequest.Files的组件进行单元测试?据我所知,没有公共API允许您在SimpleWorkerRequest上指定它。即使您可以找到可以设置HttpFileCollection属性的位置,请注意其构造函数是内部的,因此您甚至无法创建该类型的实例。

HttpRequest.Files在这方面并不孤单,实际上你可能用可以测试无法测试当前HttpContext实现的东西要多得多吗? 。这就是抽象真正派上用场的地方。

答案 1 :(得分:2)

有几种情况需要考虑。

场景一:你是单元测试。你有一些小东西,比如一个管理访问缓存的类,并且显式调用HttpContent.Cache。在这种情况下,模拟上下文,以便您可以看到正在进行的调用,以及他们是否正在按照您的期望工作。

场景二:您正在进行集成测试,您正在尝试测试大型复杂页面的生成。在这种情况下,以您找到的方式为其提供真正的HttpContent对象。您的集成测试将更好地模拟真实的运行时。

答案 2 :(得分:0)

那可能有用,但是......

  • 首先,我看到一些路径,在环境中可能会有所不同。
  • 其次是否需要安装IIS?
  • 创建它需要多长时间?如果我有100个测试需要它并且需要1秒,那么这意味着我的测试运行大约一分钟或更长时间,这会导致开发人员少运行测试。
  • 您可以轻松地模拟/设置缓存,请求等以创建测试场景吗?

模拟/存根可能更容易。

修改

在Mono项目中找到HttpContext和SimpleWorkerRequest的一些源代码:

这些可以更好地洞察创作中发生的事情。

找到一篇可能有用的文章:ASP.NET CreateApplicationHost/SimpleWorkerRequest API Hole

这实际上很好地说明了我们需要在应用它们之前理解这些对象中发生的事情并且需要时间。模拟似乎更容易。