模拟ParentActionViewContext MVC.Net

时间:2010-07-16 16:02:56

标签: 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);
}

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

非常感谢任何帮助。

1 个答案:

答案 0 :(得分: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");
    }
}

希望这有帮助!

迈克尔·伊巴拉