我可以使用动态重定向HttpContext.Current.Request吗?

时间:2012-06-25 22:55:42

标签: c# dynamic rhino-mocks

我使用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这样的例子。这可能吗?

1 个答案:

答案 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在被问到时返回表单字段值。它可能是迂回的,但它的确有效。此代码仅存在于测试代码中,因此我对此感到满意。