如何使用假对象为依赖项单元测试静态方法?

Mat*_*tin 1 c# unit-testing

我已经准备好HttpRequest的Fake对象(包装器和接口)...因为我不需要调用构造函数,如何在不破坏此方法的接口的情况下传递假的HttpRequest?

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

编辑:Akselson的解决方案是最有创意的,这个概念证明工作,令我惊讶,虽然我也使用了Skeet的解决方案,因为它看起来更有可能适用于所有情况.

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

一个选择是引入另一个重载:

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.
   }
}
Run Code Online (Sandbox Code Playgroud)

然后,您将"不可测试"(或至少"难以测试")代码减少到简单的重定向...您可以测试接受请求的版本.

  • 您可以使第二个重载内部并通过InternalsVisibleTo属性从测试程序集中使用它.因此,您不要将API混乱用于单元测试. (6认同)