单元测试WebForm的UI逻辑及文件上传

简介:

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<HttpResponseBase> FakeResponse;

  [TestMethod]
  public void LoadOk()
  {
FakeResponse = new Mock<HttpResponse>();

StringWriter sw = new StringWriter();
FakeResponse.SetupGet(x=>x.OutPut).Returns(sw);
this._response = FakeResponse.Object;

FakeResponse.Setup(x=>x.Write(It.IsAny<string>())).CallBack<string((x)=>
{
  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<HttpRequestBase>();
  FakeFiles = new Mock<HttpFileCollectionBase>();
  FakeFile = new Mock<HttpPostedFileBase>();

  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)
  {
  }
}
复制代码

本文转自最课程陆敏技博客园博客,原文链接:http://www.cnblogs.com/luminji/archive/2012/11/30/2796032.html,如需转载请自行联系原作者 

相关文章
|
6月前
|
前端开发 测试技术 API
测试金字塔:别再只盯着UI自动化了
测试金字塔:别再只盯着UI自动化了
606 116
|
6月前
|
Java 测试技术 数据库连接
【SpringBoot(四)】还不懂文件上传?JUnit使用?本文带你了解SpringBoot的文件上传、异常处理、组件注入等知识!并且带你领悟JUnit单元测试的使用!
Spring专栏第四章,本文带你上手 SpringBoot 的文件上传、异常处理、组件注入等功能 并且为你演示Junit5的基础上手体验
1078 3
|
7月前
|
Web App开发 测试技术 Linux
文件上传测试用例
测试一个文件上传组件,从客户端(Windows操作系统)向服务器端(Linux操作系统)上传一个图片文件(先选择要上传的文件,再点击【上传】按键进行上传),格式必须是JPG、PNG(大小写不敏感),文件大小必须控制在500M之内。上传后图片的名称不发生变化。请设计测试用例,测试这个文件上传组件。以下是针对文件上传组件的测试用例设计,主要涵盖了不同的上传场景,以确保组件在各种情况下都能正常工作
326 1
|
存储 人工智能 编译器
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
980 11
【03】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-测试hello word效果-虚拟华为手机真机环境调试-为DevEco Studio编译器安装中文插件-测试写一个滑动块效果-介绍诸如ohos.ui等依赖库-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
|
Java 测试技术 持续交付
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
1245 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
760 2
|
SQL 分布式计算 Hadoop
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(一)
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(一)
326 4
|
SQL
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(二)
Hadoop-14-Hive HQL学习与测试 表连接查询 HDFS数据导入导出等操作 逻辑运算 函数查询 全表查询 WHERE GROUP BY ORDER BY(二)
436 2
|
JavaScript 前端开发 安全
[译] 在 Vue 组件中分离 UI 和业务逻辑。
[译] 在 Vue 组件中分离 UI 和业务逻辑。
|
前端开发 测试技术 UED
【测试效率对比】深入分析:为何UI自动化测试的投资回报率通常低于接口自动化测试?
这篇文章深入分析了UI自动化测试与接口自动化测试的投资回报率(ROI)问题,指出UI自动化测试在某些情况下的ROI并不低,反驳了没有实施过UI自动化就轻易下结论的观点,并强调了实践的重要性和自动化测试在项目迭代中的作用。
566 1