我有一个从HttpApplication派生的类,它添加了一些额外的功能。我已经到了需要对这些特性进行单元测试的地步,这意味着我必须能够创建HttpApplication的新实例、伪造请求和检索响应对象。
我到底该如何对HttpApplication对象进行单元测试?我现在正在使用Moq,但我不知道如何设置所需的模拟对象。
发布于 2009-07-25 16:25:44
不幸的是,这并不是特别容易做到的,因为HttpApplication本身不容易被模仿;没有可以模仿的接口,而且大多数方法都没有被标记为虚拟的。
我最近在使用HttpRequest和HttpWebResponse时遇到了类似的问题。最后,我选择的解决方案是为我想要使用的方法创建一个直接的“直通”包装器:
public class HttpWebRequestWrapper : IHttpWebRequestWrapper
{
private HttpWebRequest httpWebRequest;
public HttpWebRequestWrapper(Uri url)
{
this.httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
}
public Stream GetRequestStream()
{
return this.httpWebRequest.GetRequestStream();
}
public IHttpWebResponseWrapper GetResponse()
{
return new HttpWebResponseWrapper(this.httpWebRequest.GetResponse());
}
public Int64 ContentLength
{
get { return this.httpWebRequest.ContentLength; }
set { this.httpWebRequest.ContentLength = value; }
}
public string Method
{
get { return this.httpWebRequest.Method; }
set { this.httpWebRequest.Method = value; }
}
public string ContentType
{
get { return this.httpWebRequest.ContentType; }
set { this.httpWebRequest.ContentType = value; }
}
}等等,等等
这让我嘲笑我自己的包装器接口。这不一定是世界上最优雅的东西,但却是一种非常有用的方法,可以用来模仿框架中一些不太“可模仿”的部分。
但是,在您匆忙执行此操作之前,有必要回顾一下您已获得的内容,并查看是否有更好的测试方法来避免您必须包装类。
在HttpWebRequest,HttpApplication等人的案例中,通常没有IMHO。
为了在mock中设置这个包装器(使用上面的HttpWebRequest示例),您可以使用Moq执行以下操作:
var mockWebRequest = new Mock<IHttpWebRequestWrapper>();
mockWebRequest.SetupSet<string>(c => c.Method = "POST").Verifiable();
mockWebRequest.SetupSet<string>(c => c.ContentType = "application/x-www-form-urlencoded").Verifiable();
mockWebRequest.SetupSet<int>(c => c.ContentLength = 0).Verifiable();发布于 2009-07-25 16:07:33
通过扩展HttpApplication来添加功能并不是最好的做法。由于私有/内部/密封类,模拟HttpContext非常困难,即使您成功了,您的单元测试也会被模拟代码弄得乱七八糟,以至于您将无法再理解您实际测试的是什么。
您能提供更多关于您正在添加的功能的详细信息吗?也许有一种更好的方法可以将此功能添加到应用程序中。
发布于 2011-03-17 20:55:44
我早些时候找到了下面的博客,它解释了一种使用Microsoft Moles的很好的方法。
http://maraboustork.co.uk/index.php/2011/03/mocking-httpwebresponse-with-moles/
简而言之,该解决方案提出了以下建议:
[TestMethod]
[HostType("Moles")]
[Description("Tests that the default scraper returns the correct result")]
public void Scrape_KnownUrl_ReturnsExpectedValue()
{
var mockedWebResponse = new MHttpWebResponse();
MHttpWebRequest.AllInstances.GetResponse = (x) =>
{
return mockedWebResponse;
};
mockedWebResponse.StatusCodeGet = () => { return HttpStatusCode.OK; };
mockedWebResponse.ResponseUriGet = () => { return new Uri("http://www.google.co.uk/someRedirect.aspx"); };
mockedWebResponse.ContentTypeGet = () => { return "testHttpResponse"; };
var mockedResponse = "<html> \r\n" +
" <head></head> \r\n" +
" <body> \r\n" +
" <h1>Hello World</h1> \r\n" +
" </body> \r\n" +
"</html>";
var s = new MemoryStream();
var sw = new StreamWriter(s);
sw.Write(mockedResponse);
sw.Flush();
s.Seek(0, SeekOrigin.Begin);
mockedWebResponse.GetResponseStream = () => s;
var scraper = new DefaultScraper();
var retVal = scraper.Scrape("http://www.google.co.uk");
Assert.AreEqual(mockedResponse, retVal.Content, "Should have returned the test html response");
Assert.AreEqual("http://www.google.co.uk/someRedirect.aspx", retVal.FinalUrl, "The finalUrl does not correctly represent the redirection that took place.");
}https://stackoverflow.com/questions/1182338
复制相似问题