解析ASP.NET MVC项目中视图的单元测试(2)_.Net教程
推荐:谈.NET平台编程语言的未来在去年的PDC2008召开期间,微软逐步公开了围绕.NET和编程语言的很多想法,据此我们可以饶有兴趣地对.NET的未来预测一番。 .NET平台以运行在通用语言运行时(Common Language Runtime,CLR)上的C#和VB.NET作为开端。CLR是通用语言架构(Common Language Infrast
此外,TestViewData还有一些静态方法:
public class TestViewData
{
static TestViewData()
{
PersistentProvider = new InProcPersistentProvider();
}
public static IPersistentProvider PersistentProvider { get; set; }
public static string GenerateHostUrl(TestViewData data)
{
var key = PersistentProvider.Save(data);
return ViewHostHandlerUrl "?key=" HttpUtility.UrlEncode(key);
}
private static string ViewHostHandlerUrl
{
get
{
return ConfigurationManager.AppSettings["UnitView_ViewHostHandlerUrl"]
?? "/UnitView/ViewHostHandler.ashx";
}
}
internal static TestViewData Load(string key)
{
return PersistentProvider.Load(key);
}
...
}
GenerateHostUrl方法将委托PersistentProvider保存对象,并得到一个key。这个key将拼接在ViewHostHandlerUrl属性上,这便是被测试的路径。从代码中可以看出,如果您不想使用默认的测试路径,只需在web.config的AppSettings节点中添加一个目标地址即可。
PersistentProvider属性为IPersistentProvider接口类型,其中定义了Save/Load/Remove三个方法。IPersistentProvider在项目中只有一个实现:InProcPersistentProvider,它会将TestViewData存放在内存中的一个字典里。这个实现已经足够让UnitView结合LTAF运行(LTAF的同进程特性起到了关键的作用)。不过,如果您还是希望使用WatiN等独立进程的测试工具,就必须实现自己的IPersistentProvider类型。例如您可以实现一个FilePersistentProvider,将TestViewData序列化至一个外部文件中,这样就可以在合适的时候将它取回了。
另一个较为关键的类型是UnitView.Engine.ViewHostHandler:
public class ViewHostHandler : IHttpHandler
{
private HttpContext Context { get; set; }
public void ProcessRequest(HttpContext context)
{
this.Context = context;
ControllerContext controllerContext = new ControllerContext(
new HttpContextWrapper(context),
this.Data.RouteData,
new MockController());
new ViewResult
{
MasterName = this.Data.MasterName,
ViewName = this.Data.ViewName,
TempData = this.Data.TempData,
ViewData = this.Data.ViewData,
}.ExecuteResult(controllerContext);
}
private string Key
{
get
{
string key = this.Context.Request.QueryString["key"];
if (String.IsNullOrEmpty(key))
{
throw new ArgumentNullException("key");
}
return key;
}
}
private TestViewData m_data;
private TestViewData Data
{
get
{
if (this.m_data == null)
{
this.m_data = TestViewData.Load(this.Key);
if (this.m_data == null)
{
throw new ArgumentNullException("Cannot retrieve the data.");
}
}
return this.m_data;
}
}
public bool IsReusable { get { return false; } }
}
首先,在ProcessRequest方法会取回TestViewData,并根据这些数据构造一个ViewResult对象,最后执行它的ExecuteResult方法来输出视图内容。由于ExecuteRequest方法的需要,我们还必须构造一个ControllerContext对象,也就意味着我们还必须提供一个Controller对象和HttpContext的封装。从代码中可以看出,我们这里使用了最简单的数据。由于视图遵守“约定”,它只会从ViewData中获取数据,所以无论Controller或HttpContext是什么值都已经无关紧要了。
您可能会想,为什么会有这样的“约定”,不让视图从HttpContext对象中获取数据呢?Mock一个HttpContext对象也不是那么困难(这里要感谢各种强大的Mock框架)啊。可惜,Mock后的HttpContext很难进行序列化,这样就几乎杜绝了跨进程通信的可能,这对于使用WatiN和Selenium进行测试的朋友们无疑是一种灾难。权衡之下,老赵决定放弃对HttpContext的支持。
注1:目前UnitView基于ASP.NET MVC RC构建,当RTM发布后我会进行必要的更新。请关注老赵这篇文章和托管在MSDN Code Gallery上的代码(http://code.msdn.microsoft.com/UnitView)。
注2:在《ASP.NET MVC单元测试最佳实践》中我也包含了UnitView组件,实现略有不同——请以本篇文章为主。
分享:ASP.NET如何防止用户多次登录常见的处理方法是,在用户登录时,判断此用户是否已经在Application中存在,如果存在就报错,不存在的话就加到Application中(Application是所有Session共有的,整个web应用程序唯一的一个对象): 以下是引用片段: string strUserId = txtUser.Text; ArrayLi
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP发送Email实例(可带附件)
- js实现广告漂浮效果的小例子
- asp.net Repeater 数据绑定的具体实现
- Asp.Net 无刷新文件上传并显示进度条的实现方法及思路
- Asp.net获取客户端IP常见代码存在的伪造IP问题探讨
- VS2010 水晶报表的使用方法
- ASP.NET中操作SQL数据库(连接字符串的配置及获取)
- asp.net页面传值测试实例代码
- DataGridView - DataGridViewCheckBoxCell的使用介绍
- asp.net中javascript的引用(直接引入和间接引入)
- 三层+存储过程实现分页示例代码
- 相关链接:
- 教程说明:
.Net教程-解析ASP.NET MVC项目中视图的单元测试(2)。