2008-11-07 33 views
23

Có cách nào để (đơn vị) kiểm tra HtmlHelpers của riêng tôi không? Trong trường hợp khi tôi muốn có kiểm soát tùy chỉnh (kết xuất bởi HtmlHelper) và tôi biết requierements cho điều khiển đó làm thế nào tôi có thể viết các bài kiểm tra đầu tiên - và sau đó viết mã? Có cách nào cụ thể (tốt đẹp) để làm điều đó không?Kiểm tra HtmlHelpers trong ASP.NET MVC

Có đáng không?

Trả lời

30

Vấn đề chính là bạn phải giả mạo HtmlHelper vì bạn có thể đang sử dụng các phương thức của trình trợ giúp để lấy các tuyến đường hoặc giá trị hoặc trả về kết quả của một phương pháp mở rộng khác. Lớp HtmlHelper có khá nhiều thuộc tính và một số thuộc tính khá phức tạp như ViewContext hoặc Controller hiện tại.

This post from Ben Hart giải thích cách tạo mô hình như vậy bằng Moq. Có thể dễ dàng dịch sang một khuôn khổ giả khác.

Đây là phiên bản Rhino Mocks của tôi được điều chỉnh theo các thay đổi trong Khung MVC. Nó không kiểm tra đầy đủ nhưng nó làm việc cho tôi, nhưng tôi không mong đợi kết quả hoàn hảo:

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData) 
    { 
     var mocks = new MockRepository(); 

     var cc = mocks.DynamicMock<ControllerContext>(
      mocks.DynamicMock<HttpContextBase>(), 
      new RouteData(), 
      mocks.DynamicMock<ControllerBase>()); 

     var mockViewContext = mocks.DynamicMock<ViewContext>(
      cc, 
      mocks.DynamicMock<IView>(), 
      viewData, 
      new TempDataDictionary()); 

     var mockViewDataContainer = mocks.DynamicMock<IViewDataContainer>(); 

     mockViewDataContainer.Expect(v => v.ViewData).Return(viewData); 

     return new HtmlHelper(mockViewContext, mockViewDataContainer); 
    } 
+2

buồn bã bưu lỗi trên blog nhưng giải thích ở trên khá tốt những gì bạn cần làm – MJJames

+1

Hình như họ đã thay đổi các MV C framework một chút kể từ trên như ViewContext bây giờ mất một TextWriter cũng –

+4

Điều này là siêu hữu ích, nhưng thử nghiệm chống lại MVC3 Tôi đã phải tinh chỉnh điều này bằng cách thêm một tham số mới vào mockViewContextConstructor (tôi đã sử dụng 'TextWriter.Null') và thay vì mockViewDataContainer, tôi phải đặt ViewData một cách rõ ràng (ví dụ: 'mockViewDataContainer.ViewData = viewData;') hoặc Rhino Mocks ném một ngoại lệ. –

0

Tôi đang tạo helper tùy chỉnh, và điều này là mã tôi đang sử dụng để chế nhạo các httphelper với Moq và ASP MVC 2. Tôi cũng đi qua như một tham số một giả của HttpRequestBase. Bạn có thể loại bỏ nếu bạn không cần nó

 
public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData, Mock requestMock) 
     { 
      var contextBaseMock = new Mock(); 
      contextBaseMock.SetupGet(cb => cb.Request).Returns(requestMock.Object); 

      var cc = new ControllerContext(contextBaseMock.Object, 
              new RouteData(), 
              new Mock().Object); 
      var vctx = new ViewContext(
       cc, 
       new Mock().Object, 
       viewData, 
       new TempDataDictionary(), 
       new HtmlTextWriter(new StreamWriter(new MemoryStream()))); 

      var mockViewDataContainer = new Mock(); 

      mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData); 

      return new HtmlHelper(vctx, mockViewDataContainer.Object); 
     } 
9

Nếu bất cứ ai đang tìm kiếm cách tạo HtmlHelper<T> (đó là những gì tôi đã sau), đây là một thực hiện có thể giúp - loại của tôi là một lớp có tên mẫu :

public static HtmlHelper<Model> CreateHtmlHelper() 
{ 
    ViewDataDictionary vd = new ViewDataDictionary(new Model()); 

    var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object, 
                new RouteData(), 
                new Mock<ControllerBase>().Object); 

    var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object); 

    var mockViewDataContainer = new Mock<IViewDataContainer>(); 
    mockViewDataContainer.Setup(v => v.ViewData).Returns(vd); 

    return new HtmlHelper<Model>(viewContext, mockViewDataContainer.Object); 
} 

Hoặc một thực hiện chung chung hơn:

public HtmlHelper<T> CreateHtmlHelper<T>() where T : new() 
    { 
     var vd = new ViewDataDictionary(new T()); 

     var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object, 
                 new RouteData(), 
                 new Mock<ControllerBase>().Object); 

     var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object); 

     var mockViewDataContainer = new Mock<IViewDataContainer>(); 
     mockViewDataContainer.Setup(v => v.ViewData).Returns(vd); 

     return new HtmlHelper<T>(viewContext, mockViewDataContainer.Object); 
    } 
Các vấn đề liên quan