views:

282

answers:

2

I've got my Fake object for HttpRequest ready (a wrapper and an interface)... since I don't need to call a constructor, how do I pass in the fake HttpRequest without breaking the interface of this method?

public static int ParseQueryInt(string key, int defaultValue)
{
   NameValueCollection nvc;
   if (HttpContext.Current.Request.QueryString["name"] != null)
   {
      //Parse strings.
   }
}

EDIT: Akselson's solution is the most creative and this proof of concept worked, much to my surprise, although I also used Skeet's solution as it look more likely to work in all situations.

public class Class1
{  
    [Test]
    public void Test()
    {
        HttpContext.Current = new HttpContext(
new HttpRequest("test.aspx", "http://test.com/test.aspx", "querystring=value"),
new HttpResponse(new StringWriter())
);
        Assert.AreEqual(HttpContext.Current.Request.QueryString["querystring"], "value");
    }
}
+6  A: 

One option is introduce another overload:

public static int ParseQueryInt(string key, int defaultValue)
{
    return ParseQuery(key, defaultValue, HttpContext.Current.Request);
}

public static int ParseQueryInt(string key, int defaultValue, 
                                HttpRequest request)
{
   NameValueCollection nvc;
   if (request.QueryString["name"] != null)
   {
      //Parse strings.
   }
}

Then you reduce your "untestable" (or at least "hard to test") code to a simple redirection... you can test the heck out of the version which accepts a request.

Jon Skeet
Wau, this was fast! And you were reading my mind too :)
Petar Repac
You could make the second overload internal and use it from test assembly by way of InternalsVisibleTo attribute. So you don't clutter your API for unit testing purposes.
Petar Repac
+4  A: 

You can set HttpContext.Current to your own instance:

HttpContext.Current = new HttpContext(
    new HttpRequest("test.aspx","http://test.com/test.aspx","querystring=value"),
    new HttpResponse(new StringWriter())
);

It might be useful if you don't want to change the method before you have it under test.

Akselsson