MVC依赖于HTTPContext的测试操作
我有一个需要提供操作测试的项目。我的approuch一直在确保操作不依赖于任何他们没有收到的参数,从而使用ValueProviders和ModelBinder。因此,我会通过HTTPContextBase等MVC依赖于HTTPContext的测试操作
但是,我现在有一个动作,它使用静态类是HTTPContext的包装来访问会话和身份。因此,似乎我必须模拟出HTTPContext来测试此操作。我想不是太复杂,但它只是感觉不对。
我的直觉是应该重新开发静态类,以便使用HTTPSessionStateBase和IPrinicple实例化并将它们用作内部存储。然后,我可以在动作中从动作参数中实例化这个包装器,使动作和包装器类更友好。
这是一个建议approuch或没有任何人有任何其他的想法,我是不是会改变我的静态类为实例吗?
我认为使用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)的情况。它并不是很复杂,因为你是Mocking,并不意味着你必须构建完整的,真实的对象及其所有属性。
假设您的控制器将
- 检查是否用户进行身份验证。
- 获取标识名称。
- 从Session [“key”]中获取一个值。
- 操纵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;
.....
......
}
实现模拟会话时所写的内容非常复杂! – gdoron
问题是Contoller的HttpContext是从静态ASP.NET HttpContext中设置的。因此,简单地构建HttpContextBase并将其附加到Controller的上下文不会影响静态HttpContext。我的动作调用一个静态包装器,它无法访问ControllerContext并直接访问ASP.NET HttpContext。除非我误解了某些东西,否则我觉得这个设计是有缺陷的,静态包装应该被重新开发为一个采用控制器的HttpContext的实例,然后我可以嘲笑它的生活......如果我选择。 – ricardo
我认为你是对的。既然你选择了静态保存的东西。你失去了灵活性(但它可能会节省一些资源的好处) –
有一个快速浏览一下他们,特别是我的情况,看来你是能够建立一个控制范围内,但不会出现是初始化ASP的HTTPContext.Current的任何东西。因此,当我的动作调用静态包装类时,它依次尝试访问HTTPContext.Current.Session,我得到一个错误。我想我只需要经历在我的测试中初始化HTTPContext.Current的痛苦? – ricardo
@ricardo它看起来像你不使用DI。注入httpContext并且所有的问题都会消失......使用静态httpContext.Current是一个错误,你可以在你的情况下看到它。祝你好运! – gdoron