.NET:我如何对这种方法进行单元测试?

时间:2010-11-18 14:33:04

标签: c# .net unit-testing

(类似于.NET how to fudge the HttpContext object!)

我有一个我想测试的方法:

    public void MyMethod()
    {
        if (HttpContext.Current.Application["myValue"] != null)
            Console.WriteLine("Boo!");
    }

如何在不重构方法的情况下编写测试以便Console.WriteLine被击中?

我尝试过:

        TextWriter tw = new StringWriter();
        HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", @"path...", "logon.asp", "", tw);
        HttpContext.Current = new HttpContext(wr);
        HttpContext.Current.Application.Add("KeyValue", "myValue");
        MyMethod();

但是HttpContext.Current.Application.count始终为零,我无法为其添加值!

4 个答案:

答案 0 :(得分:4)

应该重构这个方法,以便更容易测试!要正确测试此项,您需要模拟HttpContext(以下是关于如何:How to use Rhino Mocks to Mock an HttpContext.Application)的一个示例。

答案 1 :(得分:3)

如果您特别禁止重构该方法并且还需要对其进行测试,则可以使用绕行系统(例如MolesTypeMock Isolator)来完全绕开静态和HttpContext调用。然而,这可能会有点难看,而且对原始代码执行重构更为可取。


迂回嘲笑的顺序是:

  1. 绕过HttpContext.Current返回一个HttpContext绕行存根(你自己的实现符合HttpContext类接口,但看起来与测试代码的HttpContext完全相同。)

  2. 在你的HttpContext绕行存根中,模拟Application [“myValue”]来返回你想要的值(在这种情况下为null或非null。)这可能需要为Application的返回值创建一个绕行类

  3. 现在您可以配置绕行并运行您的方法。对HttpContext.Current和HttpContext方法的调用将通过Profiling API重新路由到您的绕行存根。

答案 2 :(得分:3)

您可以使用www.koders.com - Subtext.TestLibrary

中的HttpSimulator课程

只需调用

new Subtext.TestLibrary.HttpSimulator().SimulateRequest();

正确设置HttpContext,因此您还可以向Application词典添加值。

正如杰夫所说,它使用反射设置HttpApplicationFactory._theApplicationFactory._state,如下所示,但实际上你不必为此烦恼。

Type appFactoryType = Type.GetType("System.Web.HttpApplicationFactory, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
object appFactory = ReflectionHelper.GetStaticFieldValue<object>("_theApplicationFactory", appFactoryType);
ReflectionHelper.SetPrivateInstanceFieldValue("_state", appFactory, HttpContext.Current.Application);

答案 3 :(得分:0)

HttpContext.Application由您无法正常访问的私人单身人士提供。

可能能够通过反思设置这个,但我个人甚至都不会打扰。

相反,您应该将可测试代码与HttpContext.Current之类的全局状态隔离开来:只需将您要查找的值传递给您要测试的方法。

您可以清楚地看到Reflector中的代码(或者如果您已经下载了.NET代码中的代码中的代码):HttpContext.Application get访问器返回一个新的HttpApplicationState实例每次调用,除非某些内容(如ASP.NET框架)设置HttpApplicationFactory._theApplicationFactory._state