2010-07-16 24 views
1

我無法找到一個解決方案模擬ControllerContext.ParentActionViewContext。 這裏是我的控制器模擬ParentActionViewContext MVC.Net


[ChildActionOnly] 
public ViewResult Menu() 
{ 
string controller = ControllerContext.ParentActionViewContext.RouteData.Values["controller"].ToString(); 
string action = ControllerContext.ParentActionViewContext.RouteData.Values["action"].ToString(); 
List menuItems = new List(); 

...code to populate my list... 

return View(menuItems); 
} 

的代碼,我想做到的是在測試模擬ParentActionViewContext這樣我就可以通過任何控制器和動作我想要做我的模擬。 我可以模擬ControllerContext的RouteData,但我不能僞造父控制器的一個。 也許我錯過了一些obviuos。

任何幫助,非常感謝。

回答

5

你不會錯過任何明顯的東西。您已經發現ControllerContext的ParentActionViewContext屬性未標記爲虛擬,因此不可嘲弄。然而,你可以通過用你想要的值創建一個ViewContext對象來完成你想要的任務,用「ParentActionViewContext」鍵將該對象添加到RouteData.DataTokens字典中。

您可以查看ControllerContext類的源代碼以及http://bit.ly/ku8vR4的ParentActionViewContext屬性的實現。

下面是我在我的測試中實現這一點:

[TestFixture] 
public class SomeControllerTests 
{ 
    private PartialViewResult _result; 
    private Mock<HttpContextBase> _mockHttpContext; 
    private HttpContextBase _httpContext; 
    private RouteData _routeData; 
    private RouteData _parentRouteData; 


    [Test] 
    public void CanDoSomething() 
    { 
     SetupAnonymousUser(); 
     SetupHttpContext(); 
     SetupRouteData(); 
     var controller = new FooController(); 

     controller.ControllerContext = new ControllerContext(_httpContext, _routeData, controller); 

     _result = controller.Index() as PartialViewResult; 

     var model = _result.ViewData.Model as FooViewModel; 

     Assert.IsNotNull(model); 
     Assert.AreEqual("New", model.UserStatus); 
     Assert.AreEqual("21", model.PromoId); 
    } 

    private void SetupHttpContext() 
    { 
     _mockHttpContext = new Mock<HttpContextBase>(); 
     _httpContext = _mockHttpContext.Object; 
    } 

    private void SetupRouteData() 
    { 
     SetupParentRouteData(); 
     var viewContext = new ViewContext {RouteData = _parentRouteData}; 

     _routeData = new RouteData(); 
     _routeData.Values.Add("controller", "foo"); 
     _routeData.Values.Add("action", "index"); 
     _routeData.DataTokens["ParentActionViewContext"] = viewContext; 
    } 

    private void SetupParentRouteData() 
    { 
     _parentRouteData = new RouteData(); 
     _parentRouteData.Values.Add("controller", "home"); 
     _parentRouteData.Values.Add("action", "index"); 
    } 
} 

希望這有助於!

Michael Ibarra

+0

謝謝。我經過了很多「挖掘」之後最終得到了類似的東西:) – Iridio 2011-05-20 10:35:36