我有一個派生自HttpApplication的類,它增加了一些額外的功能。我到了需要對這些功能進行單元測試的地步,這意味着我必須能夠創建HttpApplication的新實例,僞造請求並檢索響應對象。單元測試HttpApplication
我到底該如何去測試一個HttpApplication對象的單元測試?目前我正在使用Moq,但我不知道如何設置所需的模擬對象。
我有一個派生自HttpApplication的類,它增加了一些額外的功能。我到了需要對這些功能進行單元測試的地步,這意味着我必須能夠創建HttpApplication的新實例,僞造請求並檢索響應對象。單元測試HttpApplication
我到底該如何去測試一個HttpApplication對象的單元測試?目前我正在使用Moq,但我不知道如何設置所需的模擬對象。
不幸的是,這並不是特別容易做到,因爲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等人,經常沒有恕我直言。
爲了設置此包裝在模擬(使用上面我的HttpWebRequest的例子),那麼你做的東西像這樣用起訂量:
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();
恕我直言,通過擴展HttpApplication添加功能不是最好的事情。由於私有/內部/密封類,嘲諷HttpContext是如此困難,即使你成功了,你的單元測試也會因爲模擬代碼而變得混亂,以至於你將不再能夠理解你正在測試的內容。
您能否提供更多關於您要添加的功能的詳細信息?也許有更好的方式將這種功能添加到您的應用程序中。
我發現下面的博客早些時候解釋了使用微軟的痣相當不錯的方法。
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.");
}
感謝您的信息!我重構了一些東西,所以現在大多數額外的功能都在外部類中,只能使用模擬的HttpContextBase而不是依賴HttpApplication來創建。 – 2009-07-25 18:13:42