0

I'm using RhinoMocks for testing. It's not good at redirecting statics; I've considered using another library like the successor to Moles (edit: I guess the Fakes tool is only available in VS2012? that stinks) or TypeMock, but would prefer not to.

I have a 3rd party library that takes in an HttpRequest object. My first stab at it was to use:

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);

All looked fine, until I went to test it. The real issue here is that I need to stub out wrapper.ApplicationInstance.Context.Request. Which leads into a whole host of old school 'ASP.NET don't like testing' pain.

I have heard that you can use dynamic magic in C# to redirect static methods. Can't find any examples of doing this with something like HttpContext though. Is this possible?

jcollum
  • 43,623
  • 55
  • 191
  • 321

1 Answers1

0

Not an ideal solution, but my solution to test this was to use reflection and modify the object under the hood:

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);

My goal here was to have wrapper.ApplicationInstance.Context.Request return a form field value when asked. It may have been roundabout, but it works. This code only exists in test code so I'm happy with it.

jcollum
  • 43,623
  • 55
  • 191
  • 321