博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单元测试WebForm的UI逻辑及文件上传
阅读量:7062 次
发布时间:2019-06-28

本文共 2715 字,大约阅读时间需要 9 分钟。

BS系统中的UI部分的逻辑测试,最首要的就是要模拟请求(Request)和输出(Response),而WebForm又跟MVC不一样,后者的Response,Request等HTTP上下文对象均有接口支持,很容易模拟,而查看WebForm的对应对象,如Response,我们首先看到的声明就是:

public sealed class HttpResponse

无接口,并且是sealed,换句话说,我们要测试一个如下的的Code-Behind函数的逻辑正确性,该怎么测试:

protected void Page_Load(object sender, EvengArgs e){  this.Response.Write("test u");}

好在FCL中有现成的包装类HttpResponseWrapper来解决我们的烦恼(不然得自己写包装类),我们将上面的代码改成如下的形式,它就可以变得可测试:

protected HttpResponseBase _response;protected override void OnPreLoad(EventArgs e){  base.OnPreLoad(e);  _response = new HttpResponseWrapper(this.Response);}protected void Page_Load(object sender, EvengArgs e){  _response.Write("test u");}

上面的重构,并不影响原有功能的实现,同时却将代码修改成可测试的,

1:首先,this.Response被替代成可以被模拟的HttpResponseBase;

2:其次,方法Page_Load内部不再负责生成被依赖的对象的生成;

         即,我们将_response的生成放到方法的外部。这个外部,可以是构造器等,不过由于webform本身的特殊性,在构造器中,this.Response上下文还不可用,所以在这个例子中放到了OnPreLoad中。 

接下来看看测试类的编写,先说点额外话,Page_Load是protected的,要让测试类可以访问到它,需改成public或者干脆让测试类继承我们的当前页面,这里采用的是后者:

[TestClass]public class _DefaultTest: _Default        ////很明显,这里测试的是Default.aspx.cs这个类{  public Mock
FakeResponse; [TestMethod] public void LoadOk() {FakeResponse = new Mock
();StringWriter sw = new StringWriter();FakeResponse.SetupGet(x=>x.OutPut).Returns(sw);this._response = FakeResponse.Object;FakeResponse.Setup(x=>x.Write(It.IsAny
())).CallBack
{ sw.Write(x); sw.Flush();}this.Page_Load(null,null);Assert.AreEqual( “test u”, (FakeResponse.Object.Output as StringWriter).ToString(); }}

首先,这个测试方法要测试的是Page_Load方法的逻辑正确性,即:执行完毕,客户端输出“test u”,它所依赖的是Response.Write这个方法,这个方法是向客户端浏览器输出文本,显然我们的单元测试中是不允许网络传输的,所以我们只能将Response.Write这个行为模拟到内存中去,测试代码中很大一部分就是模拟这个行为。要深刻理会的是:

1:我们要验证的是Page_Load行为的准确性,而不是验证Response.Write的准确性;

2:Response.Write是Page_Load行为中的一种依赖,测试方法要对这种依赖进行模拟;

备注:Response.Write内部使用TextWriter,模拟的时候,我们使用了TextWriter的一个子类,StringWriter。 

上面的例子很简单,进一步看,我们如何来写针对文件上传的单元测试。假设上传的逻辑是这样的:

Public void UploadFile(){  Var file = _request.Files[0];  If(file.contentLength==0 || file.ContentLength > 5 * 1024 * 1024)  {throw new ArgumentException();  }  File.SaveAs(file.FileName);}

则,其中一个测试用例的代码应该象如下这样:

[TestMethod]public void ThrowExceptionIfFilelengthInvalid(){  FakeRequest = new Mock
(); FakeFiles = new Mock
(); FakeFile = new Mock
(); FakeFile.SetupGet(x=> x.ContentLength).Returns(6 * 1024 * 1024); FakeFiles.SetupGet( x=> x[0]).Returns(FakeFile.Object); FakeRequest.SetupGet( x=>x.Files).Returns(FakeFiles.Object); this._request = FakeRequest.Object; try {this.UploadFile();Assert.Fail(); } catch(ArugmentOutOfRangeException) { }}

 

转载于:https://www.cnblogs.com/luminji/archive/2012/11/30/2796032.html

你可能感兴趣的文章
oracle的全局临时表
查看>>
python用sql的limit语句进行分页
查看>>
编译安装ZABBIX客户端(代理)
查看>>
CentOS命令登录MySQL时,报错ERROR 1045 (28000)
查看>>
jsp下拉框中显示数据库信息&&jsp 下拉框从数据库中如何取值?
查看>>
Linux系统编程 --- 共享内存及内存映射【十全十美】
查看>>
如何创建一个swap文件
查看>>
mysql联合索引
查看>>
我的友情链接
查看>>
zookeeper应用场景
查看>>
mysql中explain的用法
查看>>
基于kryo序列化方案的memcached-session-manager多memcached节点配
查看>>
H5页面快速搭建之高级字体应用实践
查看>>
centos6.5、centos6.6修改ssh默认端口号
查看>>
文本文件和二进制文件
查看>>
轻量级smurf源码
查看>>
linux下桌面环境的介绍及VNC的使用
查看>>
深浅拷贝——string
查看>>
主从复制模式下跳过错误
查看>>
剑指offer17
查看>>