如何使用最小起订量模拟控制器上下文

发布于 2024-07-30 03:44:46 字数 1177 浏览 7 评论 0原文

我正在尝试最小起订量框架,但现在我遇到了障碍。 以下单元测试失败,因为 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 的示例中,我只是对需要哪些其他管道才能使上述第一个单元测试示例正常工作感到困惑。

干杯,

安德鲁

I am trying out the MOQ framework and up now I have hit a barrier. The following unit test fails because the actual value of the ViewName property is an empty string.

Could anyone point me in the right direction please as to why this is not passing the test?

[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);
}

The following also yields an empty ViewName.

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

From examples on the web which demonstrate mocking and also good TTD I am just confused as to what other plumbing I need to make either of the above first unit test example work.

Cheers,

Andrew

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

骷髅 2024-08-06 03:44:46

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

您可以在 MVC 来源

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

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

如果您正在寻找在 MVC 中使用模拟的好方法,您可能需要考虑测试您的路由(这看起来就像您在这里尝试做的那样)。 您可以 查找 Phil Haack 的帖子就这个主题来帮助您入门。

This is because you're making assumptions about how the MVC framework works. If you're relying on the conventions to locate the view, the framework actually leaves the ViewName property as String.Empty until ExecuteResult() is called.

You can see this code on line 68 of ViewResultBase.ExecuteResult within the MVC source:

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

Furthermore, you should be careful about what you're testing. As a rule of thumb, you should focus on testing the code you write, not the framework's code. Testing to make sure the view name by convention is resolved correctly is really a unit test for the framework itself, not an application built on it.

If you're looking for a good way to employ mocking in MVC, you may want to look at testing your routes (which sort of looks like what you're trying to do here). You can find a post by Phil Haack concerning just this subject to get you started.

冷心人i 2024-08-06 03:44:46

测试失败的原因是,当您没有明确指定 ViewName 时,决定 ViewName 的因素是在框架的深处。 更准确地说,我相信在视图引擎中。 因此,要按目前的情况进行测试,您必须模拟更多的请求管道。

我所做的并且建议的就是不要依赖默认值并显式指定视图:

return View("About");

然后该值将在那里进行测试而无需模拟任何内容:

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

The reason the test is failing is because what decides the ViewName when you do not specify one explicitly is in the depths of the framework. More precisely in the view engine I believe. So to test this as it stands you would have to mock out a lot more of the request pipeline.

What I do, and would recommend, is to not rely on the defaults and specify the view explicitly:

return View("About");

Then the value will be there to test without mocking anything:

var controller = new HomeController();
var result = controller.About() as ViewResult;
Assert.AreEqual("About", result.ViewName);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文