(类似于.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始终为零,我无法为其添加值!
答案 0 :(得分:4)
你应该重构这个方法,以便更容易测试!要正确测试此项,您需要模拟HttpContext
(以下是关于如何:How to use Rhino Mocks to Mock an HttpContext.Application)的一个示例。
答案 1 :(得分:3)
如果您特别禁止重构该方法并且还需要对其进行测试,则可以使用绕行系统(例如Moles或TypeMock Isolator)来完全绕开静态和HttpContext调用。然而,这可能会有点难看,而且对原始代码执行重构更为可取。
迂回嘲笑的顺序是:
绕过HttpContext.Current返回一个HttpContext绕行存根(你自己的实现符合HttpContext类接口,但看起来与测试代码的HttpContext完全相同。)
在你的HttpContext绕行存根中,模拟Application [“myValue”]来返回你想要的值(在这种情况下为null或非null。)这可能需要为Application的返回值创建一个绕行类
现在您可以配置绕行并运行您的方法。对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
。