在控制器 **外部** MVC 中模拟 HttpContext
场景
我们正在开发一个新的 MVC Web 项目,并尝试遵循本文中描述的瘦控制器模式 http://codebetter.com/iancooper/2008/12/03/the-fat-controller/
作为其中的一部分在我们的操作中,我们从缓存中检索一些导航数据(菜单结构)。
问题
我为了维护瘦控制器模式,我们希望在 ViewModel 中进行缓存检查调用,我们已经尝试过并且知道可以使用以下代码。
var cachedCategories = (List<Category>)HttpContext.Current.Cache["Categories"];
if (cachedCategories == null) {
cachedCategories = _service.GetCategories().ToList<Category>();
HttpContext.Current.Cache["Categories"] = cachedCategories;
}
然而,当谈到单元测试时,我们遇到了一个问题。由于我们没有直接将 HttpContext 传递到 ViewModel 中,因此我们不知道如何模拟 HttpContext。
我们正在使用 Moq,虽然我们有一些选项(其中之一是在实例化时将上下文从控制器传递到视图模型),但这些选项需要纯粹更改代码以使测试正常工作。
有人有什么建议吗?
Scenario
We're developing a new MVC web project and we're trying to adhere to the Skinny Controller pattern as described in this article http://codebetter.com/iancooper/2008/12/03/the-fat-controller/
As part of one of our actions we are retrieving some navigation data (Menu structure) from the Cache.
Problem
I order to maintain the skinny controller pattern we'd like to have the cache check call in the ViewModel, which we have tried and we know works, using the following code.
var cachedCategories = (List<Category>)HttpContext.Current.Cache["Categories"];
if (cachedCategories == null) {
cachedCategories = _service.GetCategories().ToList<Category>();
HttpContext.Current.Cache["Categories"] = cachedCategories;
}
However when it comes to unit testing it we hit a problem. Since we are not directly passing the HttpContext into the ViewModel we have no idea how to go about mocking the HttpContext.
We're using Moq and while we have some options (one is to pass the context from the controller to the viewmodel at instantiation) those options require changing the code purely to make the tests work.
Does anyone have any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
模拟 HttpContext 是一项艰巨的工作,因为它是您一生中会看到的最大对象之一,因此最好不要模拟它。(http://volaresystems.com/Blog/post/Dont-mock-HttpContext .aspx)
无论如何,您可以使用 MVCcontrib (http://www.codeplex.com/mvcContrib) 中的 MvcMockHelps 文件显示它是如何完成的。
mock the HttpContext is a huge work as it is one of the biggest object you will see in all your life so probably is better don't mock it.(http://volaresystems.com/Blog/post/Dont-mock-HttpContext.aspx)
Anyway you could use the one in MVCcontrib (http://www.codeplex.com/mvcContrib) the file MvcMockHelps shows how it is done.
最终我们选择修改代码以方便测试。
正如我在最初的问题中提到的,我们通过在实例化时将 HttpContext 传递给 ViewModel 来实现这一点。
Ultimately we choose to modify our code to allow for easier testing.
We accomplished this by passing the HttpContext to the ViewModel at instantiation as I mentioned in my original question.