代码之家  ›  专栏  ›  技术社区  ›  REA_ANDREW

如何用moq模拟控制器上下文

  •  6
  • REA_ANDREW  · 技术社区  · 16 年前

    我正在尝试MOQ框架,现在我遇到了一个障碍。以下单元测试失败,因为ViewName属性的实际值是空字符串。

    有人能告诉我为什么考试不及格吗?

    [TestMethod]
    public void Can_Navigate_To_About_Page()
    {
        var request = new Mock<HttpRequestBase>();
        request.Setup(r => r.HttpMethod).Returns("GET");
        var mockHttpContext = new Mock<HttpContextBase>();
        mockHttpContext.Setup(c => c.Request).Returns(request.Object);
    
        var controllerContext = new ControllerContext(mockHttpContext.Object, 
                                    new RouteData(), 
                                    new Mock<ControllerBase>().Object);
        var controller = new HomeController();
    
        controller.ControllerContext = controllerContext;
        var result = controller.About() as ViewResult;
    
        Assert.AreEqual("About", result.ViewName);
    }
    

    下面还生成一个空的viewname。

            HomeController controller = new HomeController();
            ViewResult result = controller.About() as ViewResult;
            Assert.IsNotNull(result);
            Assert.AreEqual("About", result.ViewName);
    

    从演示模拟和良好TTD的Web示例中,我只是对要使上述第一个单元测试示例工作的其他管道感到困惑。

    干杯,

    安得烈

    2 回复  |  直到 15 年前
        1
  •  7
  •   Garry Shutler    16 年前

    测试失败的原因是,当不显式指定视图名时,决定该视图名的是框架的深度。更准确地说,在视图引擎中。因此,要按现状测试它,您必须模拟出更多的请求管道。

    我建议不要依赖默认值并显式指定视图:

    return View("About");
    

    然后该值将在不模拟任何内容的情况下进行测试:

    var controller = new HomeController();
    var result = controller.About() as ViewResult;
    Assert.AreEqual("About", result.ViewName);
    
        2
  •  3
  •   krohrbaugh    16 年前

    这是因为您对MVC框架的工作方式进行了假设。如果您依赖约定来定位视图,那么框架实际上会将viewname属性保留为 String.Empty 直到 ExecuteResult() 被称为。

    您可以在第68行看到此代码 ViewResultBase.ExecuteResult 在内部 the MVC source :

    if (String.IsNullOrEmpty(ViewName)) {
       ViewName = context.RouteData.GetRequiredString("action");
    }
    

    此外,您应该小心测试的内容。根据经验,您应该关注测试 你写的代码 ,而不是框架的代码。确保按约定正确解析视图名称的测试实际上是框架本身的单元测试,而不是基于框架构建的应用程序。

    如果您正在寻找一种在MVC中使用模拟的好方法,那么您可能需要考虑测试您的路由(这看起来像您在这里要做的)。你可以 find a post by Phil Haack concerning just this subject 开始吧。

    推荐文章