2012-01-05 36 views
19

Tôi có một số mã sử dụng HostingEnvironment.MapPath mà tôi muốn kiểm tra đơn vị.Cách kiểm tra mã đơn vị sử dụng HostingEnvironment.MapPath

Làm cách nào để thiết lập HostingEnvironment để nó trả về đường dẫn chứ không phải null trong dự án thử nghiệm đơn vị (mstest) của tôi?

+0

Tại sao bạn có mã phụ thuộc vào 'HostingEnvironment.MapPath' trong ứng dụng ASP.NET MVC nơi bạn có quyền truy cập vào obj ects như 'HttpServerUtilityBase' cho phép bạn đạt được điều này và có thể dễ dàng chế nhạo và thử nghiệm đơn vị? Có lẽ bạn có thể hiển thị mã này và giải thích kịch bản để chúng tôi có thể cải thiện nó? –

+3

@DarinDimitrov: Vì tôi không biết 'HttpServerUtilityBase'. Bạn có thể thêm một ví dụ? – jgauffin

Trả lời

15

Tại sao bạn có mã phụ thuộc vào HostingEnvironment.MapPath trong ứng dụng ASP.NET MVC nơi bạn có quyền truy cập vào các đối tượng như HttpServerUtilityBase cho phép bạn đạt được điều này và có thể dễ dàng chế nhạo và thử nghiệm đơn vị?

Hãy lấy một ví dụ: một hành động điều khiển trong đó sử dụng lớp Server trừu tượng mà chúng tôi muốn kiểm tra đơn vị:

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

Bây giờ, có rất nhiều cách để đơn vị kiểm tra hành động điều khiển này. Cá nhân tôi thích sử dụng MVcContrib.TestHelper.

Nhưng hãy xem cách chúng tôi có thể thực hiện việc này bằng cách sử dụng khung mocking out-of-the-box. Tôi sử dụng Rhino Mocks ví dụ này:

[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

Điều gì sẽ xảy ra nếu chúng ta thử nghiệm một 'ApiController' chứ không phải' MVC'? –

0

Nó sẽ phụ thuộc vào khung mocking hoặc cách ly bạn đang sử dụng. Bạn có thể muốn xem xét hoặc là a) tạo loại trình bao bọc xung quanh thuộc tính tĩnh có thể được mô phỏng hoặc b) bằng cách sử dụng một khung có thể giả lập các thuộc tính tĩnh - ví dụ: Moles hoặc Typemock Isolator

-4

Chỉ cần sử dụng mã này ..

Thực hiện một tham chiếu tên thư mục mới trong thư mục gốc và thêm tập tin của bạn bên trong thư mục này.

Sử dụng này

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

Vâng, tôi đã viết một bài kiểm tra ngày hôm nay cho mã mà tôi không kiểm soát và họ đã sử dụng

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

vì vậy đây là một # phản ánh C hack để thiết lập giá trị mà

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 
Các vấn đề liên quan