MVC 测试依赖于 HTTPContext 的操作

发布于 2024-12-06 14:57:08 字数 380 浏览 6 评论 0原文

我有一个项目需要提供动作测试。我的方法是确保操作不依赖于它们未收到的任何参数,主要使用 ValueProviders 和 ModelBinders。因此,我会传入 HTTPContextBase 等。

但是,我现在有一个操作,它使用一个静态类,该静态类是 HTTPContext 的包装器来访问会话和身份。因此,看来我必须模拟 HTTPContext 来测试此操作。我想并不太复杂,但就是感觉不对。

我的直觉是,应该重新开发静态类,以使用 HTTPSessionStateBase 和 IPrinicple 进行实例化,并将它们用作内部存储。然后我可以在我的操作中从操作参数实例化这个包装器,从而使操作和包装器类对测试更加友好。

这是推荐的方法还是有人有任何其他想法,如果我不必将静态类更改为实例?

I have a project where I need to provide action tests. My approuch has been to ensure actions do not rely on anything they do not receive as parameters, maing use of ValueProviders and ModelBinders. As such I would pass in HTTPContextBase etc.

However, I now have an action which uses a static class that is a wrapper around HTTPContext to accesses Session and Identity. Thus it seems I have to mock out HTTPContext to test this action. Not too complicated, I guess, but it just feels wrong.

My gut feeling is that the static class should be redeveloped to be instantiated with HTTPSessionStateBase and IPrinicple and use them as internal stores. Then I could instantiate this wrapper in my action, from action parameters, making the action and the wrapper class much more testing friendly.

Would this be a recommended approuch or does anyone have any other ideas, were I would not have to change my static class to instance ?

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

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

发布评论

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

评论(2

深海少女心 2024-12-13 14:57:08

我认为使用 Moq 来模拟 HttpContext 正是您可能想要尝试的方式。

[TestMethod]
public void Test()
{

    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    context.Setup(c => c.Request).Returns(request.Object);

    HomeController controller = new HomeController();

    controller.ControllerContext = new ControllerContext( context , new RouteData(), controller );

    ....
    ...........
}

更新:
在这种情况下,如果你想模拟 HttpSession(如评论中提到的 gdoron)。它并不真正复杂,因为您正在嘲笑某些东西并不意味着您必须构建整个真实对象及其所有属性。

假设您的控制器将

  1. 检查用户是否经过身份验证。
  2. 获取身份名称。
  3. 从 Session["key"] 获取值。
  4. 操纵cookie。

代码可能是这样的:

[TestMethod]
public void Test()
{
    ......
    .........
    var mockedControllerContext = new Mock<ControllerContext> ();
    mockedControllerContext.SetupGet(p => p.HttpContext.Session["key"]).Returns("A value in session");
    mockedControllerContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);    
    mockedControllerContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("An identity name");
    mockedControllerContext.SetupGet(p => p.HttpContext.Response.Cookies).Returns(new HttpCookieCollection ());

    HomeController controller = new HomeController();
    controller.ControllerContext = mockedControllerContext.Object;
    .....
    ......

}

I think that using Moq to mock a HttpContext is just the way you might want to try it out.

[TestMethod]
public void Test()
{

    var context = new Mock<HttpContextBase>();
    var request = new Mock<HttpRequestBase>();
    context.Setup(c => c.Request).Returns(request.Object);

    HomeController controller = new HomeController();

    controller.ControllerContext = new ControllerContext( context , new RouteData(), controller );

    ....
    ...........
}

Updated:
In the case if you want to mock HttpSession(as gdoron mentioned in comment). It is not really complicated since you are MOCKING something doesn't means you have to build entire, real object and all of its properties.

Suppose that your controller will

  1. Checks whether user is authenticated.
  2. Gets identity name.
  3. Gets a value from Session["key"].
  4. manipulates cookie.

The code could be like that:

[TestMethod]
public void Test()
{
    ......
    .........
    var mockedControllerContext = new Mock<ControllerContext> ();
    mockedControllerContext.SetupGet(p => p.HttpContext.Session["key"]).Returns("A value in session");
    mockedControllerContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);    
    mockedControllerContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("An identity name");
    mockedControllerContext.SetupGet(p => p.HttpContext.Response.Cookies).Returns(new HttpCookieCollection ());

    HomeController controller = new HomeController();
    controller.ControllerContext = mockedControllerContext.Object;
    .....
    ......

}
安人多梦 2024-12-13 14:57:08

我强烈建议使用MvcContrib - testhelpers
了解如何使用 CodePlex
您可以从 nuget 或直接从 CodePlex 下载它
祝你好运!

I strongly recommend using MvcContrib - testhelpers
Learn how to use from CodePlex
You can download it from nuget or directly from CodePlex
Good luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文