Etc*_*tch 10 .net nunit moq asp.net-mvc-4
我目前正在使用Scott Hanselmans HTTP上下文模拟进行单元测试.这适用于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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我第一次将我的应用程序转换为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;
}
Run Code Online (Sandbox Code Playgroud)
这里有一个非常简单的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");
}
Run Code Online (Sandbox Code Playgroud)
现在,当我运行此测试时,它会对PartialViewRenderer.Render在线调用进行轰炸ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 这是以下的堆栈跟踪.
在System.Web.WebPages.DisplayModeProvider的System.Web.WebPages.DefaultDisplayMode.CanHandleContext(HttpContextBase httpContext)的System.Web.WebPages.DisplayModeProvider.<.ctor> b__2(HttpContextBase上下文).<> c__DisplayClass6.b__5(IDisplayMode模式)System.Web.Mvc.VirtualPathProviderViewEngine.GetPath上的System.Web.WebPages.DisplayModeProvider.GetAvailableDisplayModesForContext(HttpContextBase httpContext,IDisplayMode currentDisplayMode)中的System.Linq.Enumerable.WhereListIterator
1.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)处理器(ControllerContext controllerContext,String [ ] locations,String [] areaLocations,String locationsPropertyName,String name,String controllerName,String cacheKeyPrefix,Boolean useCache,String []&searchingLocations)
似乎我无法进入并模拟DisplayModeProvider. 根据MVC源代码有人有解决方案吗?我无法在任何地方找到解决方案.
首先,使用MockBehavior.Strict类似的init模拟:
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
Run Code Online (Sandbox Code Playgroud)
使用它,您可以找到与DisplayMode的依赖关系.
其次,DisplayMode是asp.net mvc 4中的新功能:
http://www.asp.net/whitepapers/mvc4-release-notes#_Toc303253810
因此,它Request.Browser确定了使用的确定视图的参数.为浏览器添加模拟:
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);
Run Code Online (Sandbox Code Playgroud)
DisplayMode实现该接口IDisplayMode,因此您应该能够(使用 Moq)创建一个要注入的模拟。DisplayModeProvider有一个SetDisplayMode(受保护的)方法,您可以通过反射调用。
| 归档时间: |
|
| 查看次数: |
6957 次 |
| 最近记录: |