0

我正在使用 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 不喜欢测试”的痛苦。

我听说你可以dynamic在 C# 中使用魔法来重定向静态方法。不过,找不到任何使用 HttpContext 之类的示例。这可能吗?

4

1 回答 1

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在被问到时返回表单字段值。它可能是迂回的,但它有效。这段代码只存在于测试代码中,所以我很满意。

于 2012-06-28T23:11:17.770 回答