2009-04-05 35 views
25

Tôi đang thực hiện một số thử nghiệm đơn vị MS đơn giản trên bộ điều khiển tiêu chuẩn, không có gì đặc biệt của tôi.Đơn vị thử nghiệm phương pháp điều khiển của tôi kết quả trong một ViewName trống?

Khi tôi kiểm tra số ViewName proprty, từ đối tượng ViewResult trả lại, đó là "" (trống).

Tôi đang bị ấn tượng rằng ViewName được ngụ ý bằng tên của View (như suggested by this MS article về kiểm tra bộ điều khiển ASP.NET MVC).

BTW, khi tôi kiểm tra ViewData, tất cả đều ở đó và chính xác.

Dưới đây là đoạn code tôi có ...

public ActionResult Index(int? page, string tag) 
{ 
    if (page == null || page <= 0) 
    { 
     page = 1; 
    } 

    var viewData = new IndexViewData 
         { 
         ... my property setters, etc ... 
         }; 
    return View(viewData); 
} 

[TestMethod] 
public void Index_Action_Should_Return_Index_View_For_Default_HomePage() 
{ 
    // Arrange. 
    var controller = PostController; // Wrapper, cause I use D.I. 

    // Act. 
    ViewResult viewResult = controller.Index(null, null) as ViewResult; 

    // Assert. 
    Assert.IsNotNull(viewResult); 
    Assert.AreEqual("Index", viewResult.ViewName); // This is false/fails. 

    var indexViewData = viewResult.ViewData.Model as IndexViewData; 
    Assert.IsNotNull(indexViewData); // This is true. 
} 

Trả lời

27

Các ViewName chỉ xuất hiện khi bạn cài đặt nó trong ViewResult. Nếu tên View của bạn khớp với tên bộ điều khiển của bạn, thì tôi sẽ kiểm tra để đảm bảo rằng ViewName là rỗng hoặc rỗng vì đó sẽ là (IMO) hành vi chính xác vì bạn không muốn đặt tên trên khung nhìn. Tôi chỉ kiểm tra xem ViewName có được đặt khi tôi dự định Chế độ xem được trả về không khớp với hành động - ví dụ: khi quay lại chế độ xem "Lỗi", chẳng hạn.

EDIT: Sau đây là nguồn cho ExecuteResult trong ViewResultBase.cs (từ RC1, tôi không có nguồn cho RTW trên máy Macintosh). Như bạn có thể thấy nó kiểm tra xem ViewName đã được đặt trực tiếp chưa và nếu không, nó sẽ kéo nó từ hành động trong dữ liệu tuyến đường của trình điều khiển ngữ cảnh. Điều này chỉ xảy ra trong ExecuteResult, được gọi sau khi hành động của bộ điều khiển của bạn đã hoàn thành.

public override void ExecuteResult(ControllerContext context) { 
     if (context == null) { 
      throw new ArgumentNullException("context"); 
     } 
     if (String.IsNullOrEmpty(ViewName)) { 
      ViewName = context.RouteData.GetRequiredString("action"); 
     } 

     ViewEngineResult result = null; 

     if (View == null) { 
      result = FindView(context); 
      View = result.View; 
     } 

     ViewContext viewContext = new ViewContext(context, View, ViewData, TempData); 
     View.Render(viewContext, context.HttpContext.Response.Output); 

     if (result != null) { 
      result.ViewEngine.ReleaseView(context, View); 
     } 
    } 
+0

Heya. Hmm. tôi không hiểu bạn đang nói gì. "ViewName chỉ xuất hiện khi bạn đặt nó trong ViewResult". Tôi nghĩ rằng khuôn khổ tự động thiết lập này? Bạn đang nói rằng nó không được thiết lập tự động? –

+0

Không. Theo như tôi có thể nói cho ViewName là null, trừ khi bạn đặt cụ thể nó. Tôi tin rằng nếu nó rỗng hoặc rỗng, nó sẽ kéo tên khung nhìn từ tên của hành động. – tvanfosson

+0

>> Tôi tin rằng nếu nó rỗng hoặc rỗng, nó sẽ kéo tên khung nhìn từ tên của hành động << Hmm .. vậy có nghĩa là nó không được rỗng, đúng không? –

0

Tên chế độ xem được đặt tự động theo khuôn khổ. Nhưng khi chúng tôi kiểm tra đơn vị, chúng tôi sẽ làm ngắn mạch khung và không có gì để đặt tên.

Vì vậy, các hành động của chúng tôi cần đặt rõ tên chế độ xem khi chúng tôi kiểm tra đơn vị. Chúng tôi cũng có thể kiểm tra trống hoặc trống nếu chúng tôi thực sự, thực sự muốn dựa vào quy ước.

2

Cá nhân tôi thấy các cơ sở thử nghiệm được cung cấp bởi MVC2 có phần vụng về. Tôi đoán có cái gì đó tốt hơn đã tồn tại, nhưng tôi đã tạo ra một lớp đơn giản để kiểm tra hành động. Tôi lập mô hình giao diện (triển khai là một câu chuyện khác) trên một lớp được cung cấp bởi mã nguồn mở tuyệt vời Java MVC framework Stripes được gọi là MockRoundTrip.

Đây là phương pháp được sử dụng để có được trang đích hành động khi thử nghiệm các hành động, được gọi là getTripDestination(). Nó trả về kết quả đúng cho dù các viewname được thiết lập một cách rõ ràng hay không

//Get the destination page of the request, using Runtime execution pattern of MVC, namely 
    //if no ViewName is explicitly set in controller, ViewResult will have an empty ViewName 
    //Instead, current action name will be used in its place 
    public string getTripDestination() 
    { 
     RouteData routeData = getRouteData(); 
     ViewResult viewResult = (result is ViewResult) ? (ViewResult)result : null; 
     string tripDestination = (viewResult != null) ? viewResult.ViewName : ""; 

     return (tripDestination != "") ? tripDestination : (String)routeData.Values["action"]; 
    } 

    private RouteData getRouteData() 
    { 
     HttpContextBase context = controller.ControllerContext.RequestContext.HttpContext; 
     return RouteTable.Routes.GetRouteData(context); 
    } 
0

Các documentation for Controller.View() trạng thái:

này quá tải phương pháp của lớp View trả về một đối tượng ViewResult có một ViewName trống tài sản. Nếu bạn đang viết bài kiểm tra đơn vị cho các hành động điều khiển , hãy tính đến thuộc tính ViewName trống cho các kiểm tra đơn vị không có tên chế độ xem chuỗi.

Khi chạy, nếu thuộc tính ViewName trống, hành động hiện tại tên được sử dụng thay cho thuộc tính ViewName.

Vì vậy, khi mong đợi một chế độ xem có cùng tên với hành động hiện tại, chúng tôi chỉ có thể kiểm tra xem đó có phải là chuỗi rỗng không.

Hoặc, phương thức Controller.View (String) sẽ đặt ViewName.

Các vấn đề liên quan