[英]C# Unit Testing: Testing a method that uses MapPath
首先,我知道這個問題非常危險: 如何在C#中進行單元測試中的MapPath
但我希望它有一個不同的解決方案。 我的問題如下:
在我的代碼中,我有一個需要驗證的對象。 我正在為每個驗證方法創建單元測試,以確保它正確驗證。 我正在創建模擬數據並將其加載到對象中,然后驗證它。 問題是在驗證過程中,當發生錯誤時,會分配錯誤代碼。 此錯誤代碼用於使用Server.MapPath從xml文件收集有關錯誤的信息。 但是,在嘗試獲取xml文件時,會拋出異常,這意味着無法找到該文件。
由於MapPath在我的驗證代碼中,而不是我的單元測試,如何讓我的單元測試識別路徑? 這個問題有意義嗎?
錯誤行(在我的驗證碼中不是我的單元測試):
XDocument xdoc = XDocument.Load(HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml"));
簡化:單元測試在我的程序中調用一個調用Server.MapPath然后失敗的方法。
我會將“文件名提供程序”抽象為一個只返回一個位置的類,然后你可以更容易地模擬它。
public class PathProvider
{
public virtual string GetPath()
{
return HttpContext.Current.Server.MapPath("App_Data/ErrorCodes.xml");
}
}
然后,您可以直接使用PathProvider類...
PathProvider pathProvider = new PathProvider();
XDocument xdoc = XDocument.Load(pathProvider.GetPath());
或者在測試中嘲笑它:
PathProvider pathProvider = new MockPathProvider(); // using a mocking framework
XDocument xdoc = XDocument.Load(pathProvider.GetPath());
經過嚴格的谷歌搜索和同事的一些幫助,我們想出了一個已經內置到.net中的簡單解決方案
在訪問驗證過程的單元測試之上,我補充說:
[TestMethod()]
[HostType("ASP.NET")]
[UrlToTest("http://localhost:###/upload_file.aspx")]
[AspNetDevelopmentServerHost("Path To Web Application", "Path To Web Root")]
這非常有效。 基本上,在調用測試時,它會在頁面加載中使用指定的單元測試加載URL。 由於它是一個現在調用單元測試的網站,因此驗證將可以訪問Server.MapPath。 這個解決方案可能並不適用於所有人,但它對此非常有用。 感謝您所貢獻的一切。
嘗試使用Rhino Mocks或替代模擬框架來模擬httpContext(或其他依賴對象)或者您可以編寫自己的模擬對象。 或者編寫一個MapPathWrapper類,從您的真實環境繼承MapPathWrapperBase類,然后在您的單元測試中創建一個MockMapPathWrapper對象。
在SO上應該有很多關於模擬的例子。
這是我問過的一個:
如何使用Rhino Mocks來模擬HttpContext.Application
更新我只有使用Asp.Net MVC的經驗,因為缺少HttpContextBase類,我會想象它會變得更加困難。
我會提取接受您的依賴項作為參數的方法:
public void Validate(HttpContext context)
{
ValidatePath(context.Server.MapPath("App_Data/ErrorCodes.xml"));
}
public void ValidatePath(string path)
{
XDocument xdoc = XDocument.Load(path);
ValidateDocument(xdoc);
}
public void ValidateDocument(XDocument xdoc)
{
// Original code
}
然后,您可以單獨測試各種方法。 例如,測試ValidatePath()
如何處理丟失的文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.