加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

.net – MVC 4 Mocking HttpContext – 如何模拟DisplayModeProv

发布时间:2020-12-15 22:15:58 所属栏目:asp.Net 来源:网络整理
导读:我目前正在使用 Scott Hanselmans HTTP context mock进行单元测试.这对MVC 3很有效,从来没有回头看,我用它来测试以下代码的调用. public class PartialViewRenderer : IPartialViewRenderer{ public string Render(Controller controller,string viewName,ob
我目前正在使用 Scott Hanselmans HTTP context mock进行单元测试.这对MVC 3很有效,从来没有回头看,我用它来测试以下代码的调用.
public class PartialViewRenderer : IPartialViewRenderer
{
    public string Render(Controller controller,string viewName,object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = controller.ControllerContext.RouteData.GetRequiredString("action");

        controller.ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext,viewName);
            ViewContext viewContext = new ViewContext(controller.ControllerContext,viewResult.View,controller.ViewData,controller.TempData,sw);
            viewResult.View.Render(viewContext,sw);

            return sw.GetStringBuilder().ToString();
        }
    }
}

当我第一次将我的应用程序转换为MVC 4时,遇到问题,它正在得到运行时异常.所以我尝试修复需要修复的内容,这使我改变了Hanselmans MockHelpers上的以下方法:(我基本上改变了HttpContext.Items,因为它被吹出了一个“null”的异常)

public static HttpContextBase FakeHttpContext()
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        var cookies = new HttpCookieCollection();
        var items = new ListDictionary();

        request.Setup(r => r.Cookies).Returns(cookies);
        response.Setup(r => r.Cookies).Returns(cookies);

        context.Setup(ctx => ctx.Items).Returns(items);

        context.SetupGet(ctx => ctx.Request).Returns(request.Object);
        context.SetupGet(ctx => ctx.Response).Returns(response.Object);
        context.SetupGet(ctx => ctx.Session).Returns(session.Object);
        context.SetupGet(ctx => ctx.Server).Returns(server.Object);

        return context.Object;
    }

 public static void SetFakeControllerContext(this Controller controller,RouteData route)
    {
        var httpContext = FakeHttpContext();

        ControllerContext context = new ControllerContext(new RequestContext(httpContext,route),controller);

        controller.ControllerContext = context;
    }

这里有一个非常简单的nUnit测试,我必须尝试并确定我需要做什么改变,这个模拟的http上下文(我甚至没有说出来)

[Test]
    public void test()
    {
        _contactsController = _container.Resolve<ContactsController>();

        var route = new RouteData();

        route.Values.Add("controller","ContactsController");
        route.Values.Add("action","GetEditContactDetailsDialog");

        _contactsController.SetFakeControllerContext(route);

        var result = _contactsController.GetEditContactDetailsDialog("1");
    }

现在当我运行这个测试它在PartialViewRenderer.Render调用onEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext,viewName);这是以下堆栈跟踪.

at System.Web.WebPages.DisplayModeProvider.<.ctor>b__2(HttpContextBase context)
at System.Web.WebPages.DefaultDisplayMode.CanHandleContext(HttpContextBase httpContext)
at System.Web.WebPages.DisplayModeProvider.<>c__DisplayClass6.b__5(IDisplayMode mode)
at System.Linq.Enumerable.WhereListIterator1.MoveNext()
at System.Collections.Generic.List
1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at System.Web.WebPages.DisplayModeProvider.GetAvailableDisplayModesForContext(HttpContextBase httpContext,IDisplayMode currentDisplayMode)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext,String[] locations,String[] areaLocations,String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String[]& searchedLocations)

看来我不能进去,嘲笑DisplayModeProvider.有没有人有解决这个问题?我没有找到任何地方的解决方案.

解决方法

首先,初始化mock与MockBehavior.Strict类似:
var context = new Mock<HttpContextBase>(MockBehavior.Strict);

使用它可以找到与DisplayMode的依赖关系.

二,DisplayMode是asp.net mvc中的新功能4:

http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253810

所以,它得到Request.Browser参数,以确定使用哪个View.添加Mock浏览器:

var browser = new Mock<HttpBrowserCapabilitiesBase>(MockBehavior.Strict);
        var context = new Mock<HttpContextBase>(MockBehavior.Strict);
        var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
        var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
        var session = new Mock<HttpSessionStateBase>(MockBehavior.Strict);
        var server = new Mock<HttpServerUtilityBase>(MockBehavior.Strict);
        var cookies = new HttpCookieCollection();
        var items = new ListDictionary();

        browser.Setup(b => b.IsMobileDevice).Returns(false);

        request.Setup(r => r.Cookies).Returns(cookies);
        request.Setup(r => r.ValidateInput());
        request.Setup(r => r.UserAgent).Returns("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML,like Gecko) Chrome/23.0.1271.64 Safari/537.11");
        response.Setup(r => r.Cookies).Returns(cookies);

        request.Setup(r => r.Browser).Returns(browser.Object);
        context.Setup(ctx => ctx.Items).Returns(items);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读