好久不写文章了,一直忙在项目中。

前一阵发现公司一个项目,体积巨大。业务很复杂。基于历史原因,项目基于mvc 2迁移过来,视图大多还是aspx  作为视图承载。

控制器中的方法  更是一个比一个多。

由于站点使用了许多开源组件,整个Bin  编译出来有将近200M!

而且里面在站点启动的时候,对远程的服务代码 进行了动态编译!导致启动一次项目很慢,调试很麻烦 等待很久,很是捉急...........

想测试个控制器的Action ,要么写代码测试,要么有HttpContext的那种 只能干等待。于是想了想,要是有能自动模拟 iis的测试工具,直接监视请求,然后调试源码。

实现原理:

基于 Owin的  Mvc 自承载。

mvc项目自承载,一个基于Owin的命令行程序,在启动的时候,Startup 中,host mvc 站点项目即可。然后就可以模拟Iis 承载mvc ,启动迅速,也不用写单元测试代码,对于复杂的

参数,也不用代码构建了。

一个比较头大的问题是:自承载的处理模型跟 iis 承载的处理模型不一样。

Owing是基于 模块组件的方式,构成调用链。对注册的中间件进行链式的调用,全程使用一个OwinContenxt

IIs 是基于管道模型,将请求 封装到 HttpConxt 中,然后基于事件的形式 在 注册的Module Handler中穿梭。

要进行模拟IIS 就必须模拟HttpContext对象!!!(除非  项目完全抛弃了使用这个对象----0-0--)

如何模拟?不好模拟,因为微软团队将这个对象的很多属性 /字段 要么 是只读的 要么是私有的。所以,只能不走寻常路:反射赋值!!!

比如:

核心代码: SimpleWorkerRequest

提供的简单实现 HttpWorkerRequest 抽象类可以使用 Internet 信息服务 (IIS) 应用程序外部托管 ASP.NET 应用程序。 您可以采用SimpleWorkerRequest 直接或对其进行扩展。

通过 SimpleWorkerRequest 构建HttpContext 对象

然后通过反射,对非公开的字段/只读属性进行赋值

Type appFactoryType = Type.GetType("System.Web.HttpApplicationFactory, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
object appFactory = ReflectionHelper.GetStaticFieldValue<object>("_theApplicationFactory", appFactoryType);
ReflectionHelper.SetPrivateInstanceFieldValue("_state", appFactory, HttpContext.Current.Application);
}

要加载那些dll 中的代码,就构建加载对应的Type  然后 反射赋值即可!

一旦能承载,那么 接下来无非就是对Mvc 的请求解析。。。(owin 自承载可以自动解析webapi的控制器,所以 对于混合项目 或者mvc项目,将mvc解析请求的基本步骤实现即可)

  var controllerOfMvc = Activator.CreateInstance(controllerDescription.ControllerType) as Controller;

                             IHttpRouteData routeData = GlobalContext.config.Routes.GetRouteData(requestMessage);
var mvcRouteData = new RouteData();
var paras = new Dictionary<string, object>();
foreach (var item in routeData.Values)
{
mvcRouteData.Values.Add(item.Key, item.Value);
paras.Add(item.Key, item.Value);
}
var ctrlContext = new ControllerContext(httpContextBase, mvcRouteData, controllerOfMvc);
var actionDescription = controllerDescription.FindAction(ctrlContext, actionName); if (null != actionDescription)
{
var actionResult = actionDescription.Execute(ctrlContext, paras) as ActionResult; string resultText = string.Empty;
if (actionResult is JsonResult)
{
var data = (actionResult as JsonResult).Data;
resultText = JsonConvert.SerializeObject(data);//序列化数据 }
else if (actionResult is ViewResult || actionResult is PartialViewResult)
{
//解析模板 实现的核心就是 视图文件虚拟化 VirtualPathProvider and 动态编译 var clientBuildManager = new ClientBuildManager(rootVirtualPath, GlobalContext.SitePhysicDir);
/*
如果 有需要 可以尝试开发出来。参考资料:
http://blog.rebuildall.net/2009/11/17/asp_net_mvc_and_virtual_views
https://blog.falafel.com/how-to-load-views-from-assembly-in-mvc/
https://msdn.microsoft.com/en-us/library/system.web.hosting.virtualpathprovider(v=vs.110).aspx
http://www.binaryintellect.net/articles/e544d1d3-e47e-4ced-bd4d-8c1eaefbdc31.aspx
http://www.danielroot.info/2013/07/reuse-mvc-views-using-virtual-path.html
https://github.com/aspnet/Mvc/issues/3750
http://www.chrisvandesteeg.nl/2010/11/22/embedding-pre-compiled-razor-views-in-your-dll/
https://stackoverflow.com/questions/236972/using-virtualpathprovider-to-load-asp-net-mvc-views-from-dlls
https://stackoverflow.com/questions/24341336/is-it-possible-to-access-mvc-views-located-in-another-project
http://ericsowell.com/blog/2007/4/3/the-asp-net-virtual-path-provider-an-example-implementation
http://tech.trailmax.info/2014/02/attempt-to-do-view-compilation-for-azure-web-role/
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/BuildManagerCompiledView.cs
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/BuildManagerCompiledView.cs
*/
throw new NotImplementedException(); string viewName = RenderHelper.ViewNameFromActionResult(actionResult);
if (string.IsNullOrEmpty(viewName))
{
viewName = actionName;
}
//定制 路径 不基于mvc标准
string viewPath = System.IO.Path.Combine( "~/Views", controllerName, string.Concat(actionName, ".aspx")).Replace("\\","/");//暂时没有ascx
//
resultText = RenderHelper.RenderWebFormViewToString(ctrlContext, actionResult, viewPath);//RenderHelper.RenderActionResultToString(ctrlContext, actionResult, mvcRouteData, controllerOfMvc); }

参考

https://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx/

  

asp.net mvc 自动化测试工具的更多相关文章

  1. ASP.NET MVC有用工具

    Route Debugger https://www.nuget.org/packages/routedebugger 在Asp.Net MVC程序中,路由(Route)是一个非常核心的概念,可以说是 ...

  2. 学习ASP.NET MVC(九)——“Code First Migrations ”工具使用示例

    在上一篇文章中,我们学习了如何使用实体框架的“Code First Migrations ”工具,使用其中的“迁移”功能对模型类进行一些修改,同时同步更新对应数据库的表结构. 在本文章中,我们将使用“ ...

  3. Pro ASP.NET MVC –第六章 MVC的基本工具

    在本章,我们将介绍每个MVC程序员"武器库"的三个重要工具:依赖注入容器.单元测试框架和mock工具.在本书,对于三个工具分别都只用了一种方式实现,但每个工具都还有其他的实现方式. ...

  4. Pro ASP.NET MVC 5 Framework.学习笔记.6.3.MVC的必备工具

    每个MVC程序员的军火库中,都有这三个工具:一个依赖注入(DI)容器,一个单元测试框架,一个模拟工具. 1.准备一个示例项目 创建一个ASP.NET MVC Web Application的Empty ...

  5. ASP.NET MVC性能优化工具 MiniProfiler

    ASP.NET MVC性能优化工具 MiniProfiler 2014年04月19日 ⁄ ASP.NET ⁄ 共 1159字 ⁄ 字号 小 中 大 ⁄ 暂无评论 ⁄ 阅读 325 views 次 MV ...

  6. Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展

    Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...

  7. 使用JSON.Net(Newtonsoft.Json)作为ASP.Net MVC的json序列化和反序列化工具

    ASP.Net MVC默认的JSON序列化使用的是微软自己的JavaScriptSerializer.性能低不说,最让人受不了的是Dictionary<,>和Hashtable类型居然对应 ...

  8. 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

    系列文章 七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)— ...

  9. 7 天玩转 ASP.NET MVC — 第 1 天

    0. 前言正如标题「7 天玩儿转 ASP.NET MVC」所言,这是个系列文章,所以将会向大家陆续推出 7 篇.设想一下,一天一篇,你将从一个愉快的周一开始阅读,然后在周末成为一个 ASP.NET M ...

随机推荐

  1. 谈谈.NET,Java,php

    开通博客后,一直都是转点别的朋友写的有意思的博文,今天我来写我在博客园的第一篇文章,说的不对的地方请你指正.希望本文能为一些准备学习编程的朋友有一点帮助. 开发桌面程序一直都是c语言,c++的天下,因 ...

  2. java.lang.ClassNotFoundException: com.sun.jna.Native

    在使用sprng boot加elasticsearch的时候遇到 java.lang.ClassNotFoundException: com.sun.jna.Native,百度之后要我导入 <d ...

  3. 第4阶段——制作根文件系统之分析init_post()如何启动第1个程序(1)

    本章学习如何启动第一个应用程序 1.在前面的分析中我们了解到,在init进程中内核挂接到根文件系统之后,会开始启动第一个应用程序: kernel_init函数代码如下: static int __in ...

  4. Linux-mount命令和umount命令 (8)

    mount:用于挂载文件系统,使能访问其它文件系统中的资源 umount:用于卸载已挂载的文件系统 mount: 格式: mount [-参数] [设备名称] [挂载点] 其中常用的参数(参数默认自带 ...

  5. jenkins+gitlab+sonar+testng构建持续集成测试环境(配置干货篇)

    几个工具的安装部分就不在此介绍了! jenkins配置: 1.插件安装 2.root私钥配置 3.构建job配置 4.部署job配置 5.测试job配置 7.jenkins全局工具配置 8.jenki ...

  6. jQuery常用工具方法

    前面的话 jQuery提供一些与元素无关的工具方法,不必选中元素,就可以直接使用这些方法.如果理解原生javascript的继承原理,那么就能理解工具方法的实质.它是定义在jQuery构造函数上的方法 ...

  7. OSI与TCP/IP网络模型分层

      学习linux的人,都会接触到一些网络方面的知识.作为一个linux方面的萌新,今天,小编就接触了OSI模型和TCP/IP协议栈,那么什么是OSI模型呢?     OSI模型,开放式系统互联通信参 ...

  8. 个人作业2 — 英语学习APP的案例分析

    一.调研准备:   1.软件:必应词典   2.平台:安卓   3.bug定义:(引用自<构建之法>13.1节)    Bug:软件的缺陷    Bug可以分解为:症状(Symptom). ...

  9. 【Beta】 第四次Daily Scrum Meeting

    一.本次会议为第四次meeting会议 二.时间:10:00AM-10:20AM 地点:陆大楼 三.会议站立式照片 四.今日任务安排 成员 昨日任务 今日任务 林晓芳 查询app提醒功能模块和用户登录 ...

  10. backtrack 使用Tab键补全命令

    刚安装个BackTrack5(基于Ubuntu)做安全测试,发现默认安全设置级别很高,连ssh服务默认都关闭,root下不能使用tab键补全命令,这个就真不方便了.原因是root的配置文件注释了三行脚 ...