模拟ParentActionViewContext MVC.Net

Iri*_*dio 1 asp.net-mvc mocking

我找不到模拟ControllerContext.ParentActionViewContext的解决方案.这是我的控制器的代码


[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);
}
Run Code Online (Sandbox Code Playgroud)

我想要完成的是在测试中模拟ParentActionViewContext,这样我就可以传递我想要进行模拟的任何控制器和动作.我可以模拟ControllerContext的RouteData,但我无法伪造父控制器之一.也许我错过了一些obviuos.

任何帮助是极大的赞赏.

小智 5

你不会错过任何明显的东西.您已经发现ControllerContext的ParentActionViewContext属性未标记为虚拟,因此不可模拟.但是,您可以通过使用所需的值创建ViewContext对象来完成所需的操作,并使用键"ParentActionViewContext"将该对象添加到RouteData.DataTokens字典中.

您可以在http://bit.ly/ku8vR4上查看ControllerContext类的源代码和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");
    }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

迈克尔伊巴拉