2012-01-05 118 views
19

我有一些代碼使用HostingEnvironment.MapPath我想單元測試。如何使用HostingEnvironment.MapPath單元測試代碼

我該如何設置HostingEnvironment,以便在我的單元測試(mstest)項目中返回一個路徑而不是null

+0

爲什麼你會有一個代碼依賴於ASP.NET MVC應用程序中的'HostingEnvironment.MapPath',你可以訪問obj像'HttpServerUtilityBase'這樣的函數可以讓你實現這一點,並且可以很容易地模擬和單元測試?也許你可以展示這些代碼並解釋這個場景,以便我們改進它? – 2012-01-05 10:09:52

+3

@DarinDimitrov:因爲我不知道'HttpServerUtilityBase'。你可以添加一個例子嗎? – jgauffin 2012-01-05 10:19:48

回答

15

爲什麼你會依賴於HostingEnvironment.MapPath代碼在ASP.NET MVC應用程序,你有喜歡的HttpServerUtilityBase訪問對象,讓你可以實現這一點,可以很容易地嘲笑和單元測試?

讓我們舉個例子:利用了我們想要的單元測試抽象服務器級別的控制器操作:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var file = Server.MapPath("~/App_Data/foo.txt"); 
     return View((object)file); 
    } 
} 

現在,有很多方法進行單元測試該控制器的動作。我個人喜歡使用MVcContrib.TestHelper

但讓我們看看我們如何使用模擬框架開箱即用。我用犀牛嘲笑這個例子:

[TestMethod] 
public void Index_Action_Should_Calculate_And_Pass_The_Physical_Path_Of_Foo_As_View_Model() 
{ 
    // arrange 
    var sut = new HomeController(); 
    var server = MockRepository.GeneratePartialMock<HttpServerUtilityBase>(); 
    var context = MockRepository.GeneratePartialMock<HttpContextBase>(); 
    context.Expect(x => x.Server).Return(server); 
    var expected = @"c:\work\App_Data\foo.txt"; 
    server.Expect(x => x.MapPath("~/App_Data/foo.txt")).Return(expected); 
    var requestContext = new RequestContext(context, new RouteData()); 
    sut.ControllerContext = new ControllerContext(requestContext, sut); 

    // act 
    var actual = sut.Index(); 

    // assert 
    var viewResult = actual as ViewResult; 
    Assert.AreEqual(viewResult.Model, expected); 
} 
+6

如果我們測試一個'ApiController'而不是'MVC'一個呢? – 2016-03-11 15:52:23

0

這取決於你使用的模擬或隔離框架。您可能想要考慮a)圍繞可以模擬的靜態屬性創建包裝類型,或者b)使用可以模擬靜態屬性的框架 - 例如MolesTypemock Isolator

-4

只要使用這個代碼..

請在根目錄下的新文件夾名稱參考,並添加您的文件這個文件夾裏面。

使用此

public static XElement GetFile() 
{ 
    HttpContext.Current = new HttpContext(new HttpRequest("", "http://www.google.com", ""), new HttpResponse(new StringWriter())); 

    var doc = new XmlDocument(); 
    var file = HttpContext.Current.Server.MapPath("\\") + "abc.xml"; 
    doc.Load(file); 
    var e = XElement.Load(new XmlNodeReader(doc)); 
    return e; 
} 
0

嗯,我在寫代碼的測試今天,我不控制,他們用

private static String GetApplicationPath() 
    { 
     return HostingEnvironment.ApplicationVirtualPath.TrimEnd('/'); 
    } 

所以這裏是一個C#反射劈死設定值

var path = "/aaaa/bb"; 

HostingEnvironment hostingEnvironment; 
if (HostingEnvironment.IsHosted.isFalse()) 
    new HostingEnvironment(); 

hostingEnvironment = (HostingEnvironment)typeof(HostingEnvironment).fieldValue("_theHostingEnvironment"); 

var virtualPath = "System.Web".assembly() 
        .type("VirtualPath").ctor(); 

virtualPath.field("_virtualPath", path); 
//return virtualPath.prop("VirtualPathString");     
//return virtualPath.prop("VirtualPathStringNoTrailingSlash");     

hostingEnvironment.field("_appVirtualPath", virtualPath); 
//hostingEnvironment.field("_appVirtualPath") == virtualPath; 

return HostingEnvironment.ApplicationVirtualPath == path;  

//using System.Web.Hosting