我正在试用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的例子我只是对于我需要做出上述第一个单元测试示例工作的其他管道工作感到困惑。

干杯,

安德鲁

有帮助吗?

解决方案

测试失败的原因是因为当您没有明确指定ViewName时,决定ViewName的是在框架的深度。更确切地说,在视图引擎中我相信。因此,为了测试它,你将不得不模拟更多的请求管道。

我所做的并且建议不要依赖默认值并明确指定视图:

return View("About");

然后值将在那里进行测试而不会嘲笑任何东西:

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

其他提示

这是因为您正在假设MVC框架是如何工作的。如果依靠约定来定位视图,框架实际上将ViewName属性保留为 String.Empty ,直到调用 ExecuteResult()

您可以在 ViewResultBase.ExecuteResult 的第68行看到此代码。 “nofollow noreferrer”> MVC来源

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

此外,您应该注意您正在测试的内容。根据经验,您应该专注于测试您编写的代码,而不是框架的代码。测试以确保按惯例正确解析视图名称实际上是框架本身的单元测试,而不是构建在其上的应用程序。

如果您正在寻找一种在MVC中使用模拟的好方法,您可能需要考虑测试您的路线(这类似于您在此尝试做的事情)。您可以查找Phil Haack的帖子关于这个主题让你开始。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top