我使用RhinoMocks进行测试。它不擅长重定向静力学;我考虑使用另一个库,比如Moles的继任者(编辑:我猜Fakes工具只在VS2012中可用?有臭味)或TypeMock,但不愿意。
我有一个第三方库,它接收一个HttpRequest对象。我第一次尝试使用:
public void GetSamlResponseFromHttpPost(out XmlElement samlResponse,
out string relayState, HttpContextBase httpContext = null)
{
var wrapper = httpContext ?? new HttpContextWrapper(HttpContext.Current);
// signature of the next line cannot be changed
ServiceProvider.ReceiveSAMLResponseByHTTPPost(
wrapper.ApplicationInstance.Context.Request, out samlResponse, out relayState);
一切都很好,直到我去测试它。这里真正的问题是我需要删除wrapper.ApplicationInstance.Context.Request
。这导致了一大堆旧学校和ASP.NET不喜欢测试'痛。
我听说您可以在C#中使用dynamic
magic来重定向静态方法。但是找不到任何像HttpContext这样的例子。这可能吗?
答案 0 :(得分:0)
不是一个理想的解决方案,但我的测试方法是使用反射并修改引擎盖下的对象:
httpRequest = new HttpRequest("default.aspx", "http://test.com", null);
var collection = httpRequest.Form;
// inject a value into the Form directly
var propInfo = collection.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
propInfo.SetValue(collection, false, new object[] { });
collection["theFormField"] = val;
propInfo.SetValue(collection, true, new object[] { });
var appInstance = new HttpApplication();
var w = new StringWriter();
httpResponse = new HttpResponse(w);
httpContext = new HttpContext(httpRequest, httpResponse);
// set the http context on the app instance to a new value
var contextField = appInstance.GetType().GetField("_context", BindingFlags.Instance | BindingFlags.NonPublic);
contextField.SetValue(appInstance, httpContext);
Context.Stub(ctx => ctx.ApplicationInstance).Return(appInstance);
我的目标是让wrapper.ApplicationInstance.Context.Request
在被问到时返回表单字段值。它可能是迂回的,但它的确有效。此代码仅存在于测试代码中,因此我对此感到满意。