asp.net 单元测试(转)
最早接触单元测试是看了极限编程相关资料里边讲的测试驱动开发,然后下载了Nunit研究了一下,但并没产生多大的触动,因为那个时候做的都是些时间紧任务重的事情,对于单元测试的直接感觉就是有可能比较费时间。直到看了《敏捷软件开发:原则、模式与实践》,里边那个保龄球计分程序很精彩,让我知道了保龄球原来是这么计分的,更重要的是让我认识到测试驱动编程原来这样有意义,并且其实并不浪费时间(至于测试驱动编程到底有意义在哪里,我这里就不说了,大家可以参阅Kent的《测试驱动开发》,Robert C. Martin的《敏捷软件开发:原则、模式与实践》,http://www.ibm.com/developerworks/cn/linux/l-tdd/,http://www.ibm.com/developerworks/cn/java/j-xp042203/等)。在webform中对web层的逻辑很难做单元测试(当然我们可以利用mvp模式(参考:http://www.cnblogs.com/bluewater/archive/2006/12/11/589214.html#1219888)来分解web层逻辑,但因为没有框架的支持,并且实现起来也不是很简单,也不是特别好理解,所以应用并不广泛)。ASP.NET MVC很好的解决了测试web逻辑的问题,可测试性也变成了ASP.NET MVC的优势之一。下面我们就来介绍一下如何在ASP.NET MVC中进行单元测试。
一、测试路由器:
我们首先利用mvc的模板创建一个解决方案,我们可以在Gloabal.asax.cs文件中发现如下代码
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
); }
下面我们就为这段代码写一个单元测试(如果对路由还不清楚请参见:ASP.NET MVC实践系列1-UrlRouting )
[TestMethod]
public void TestMvcApplicationRoute()
{
RouteCollection routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(c => c.Request
.AppRelativeCurrentExecutionFilePath).Returns("~/Home/Index"); RouteData routeData = routes.GetRouteData(httpContextMock.Object); Assert.IsNotNull(routeData, "Should have found the route");
Assert.AreEqual("Home", routeData.Values["Controller"]);
Assert.AreEqual("Index", routeData.Values["action"]);
Assert.AreEqual("", routeData.Values["id"]);
}
下面我们解释一下上面的代码
RouteCollection routes = new RouteCollection();
MvcApplication.RegisterRoutes(routes);
这两行的意思是将routes按照默认路由代码中的格式生成相应的路由。
var httpContextMock = new Mock<HttpContextBase>();
httpContextMock.Setup(c => c.Request.AppRelativeCurrentExecutionFilePath).Returns("~/Home/Index");
这两行的意思是创建一个HttpContextBase的mock类,这里我们使用的是MoQ框架来生成mock类(参见:MoQ(基于.net3.5,c#3.0的mock框架)简单介绍 )。
RouteData routeData = routes.GetRouteData(httpContextMock.Object);
这行的意思是从routes中获得路由数据,为下边断言路由中的内容作准备。
Assert.AreEqual("Home", routeData.Values["Controller"]);
Assert.AreEqual("Index", routeData.Values["action"]);
Assert.AreEqual("", routeData.Values["id"]);
这三行分别验证了路由中生成的Controller,action,id的正确性。
二、测试Controller与Action
1、测试ViewData
我们先来看一下ASP.NET MVC的默认模板中的测试代码:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View();
} //测试代码
[TestMethod]
public void Index()
{
// Arrange
HomeController controller = new HomeController(); // Act
ViewResult result = controller.Index() as ViewResult; // Assert
ViewDataDictionary viewData = result.ViewData;
Assert.AreEqual("Welcome to ASP.NET MVC!", viewData["Message"]);
}
我们可以在测试代码中对viewData的内容进行验证,一般并不推荐使用弱类型的viewData来进行传递数据,下面我们来看一下如何来测试viewModel中的内容。
public ActionResult About()
{
News news = new News() { ID = , Author = "lfm" };
return View(news);
} 测试代码 [TestMethod]
public void About()
{
// Arrange
HomeController controller = new HomeController(); // Act
ViewResult result = controller.About() as ViewResult;
Assert.AreEqual(, ((News)result.ViewData.Model).ID);
// Assert
Assert.IsNotNull(result);
}
2、测试RedirectToAction:
public ActionResult TestRedirectToAction()
{
return RedirectToAction("Index");
} //测试代码 [TestMethod]
public void TestRedirectToAction()
{
// Arrange
HomeController controller = new HomeController(); // Act
var result = controller.TestRedirectToAction() as RedirectToRouteResult; ; // Assert
Assert.IsNotNull(result);
Assert.AreEqual("Index", result.RouteValues["action"]);
}
三、测试View Helpers
我们常常会把一些牵扯到逻辑的View代码写到Helper中,所以测试Helper非常有意义,我们先写一个简单的Helper
using System;
using System.Collections.Generic;
using System.Web.Mvc;
public static class MyHelpers
{
public static string UnorderedList<T>(this HtmlHelper html, IEnumerable<T> items)
{
if (html == null)
{
throw new ArgumentNullException("html");
}
string ul = "<ul>";
foreach (var item in items)
{
ul += "<li>" + html.Encode(item.ToString()) + "</li>";
}
return ul + "</ul>";
}
}
这个Helper的完成的工作是将输入的集合数据分解然后按列表输出。
[TestMethod]
public void TestHelp()
{
var contextMock = new Mock<HttpContextBase>();
var controllerMock = new Mock<ControllerBase>();
var view = new Mock<IView>();
var cc = new ControllerContext(contextMock.Object, new RouteData(), controllerMock.Object);
var viewContext = new ViewContext(cc, view.Object, new ViewDataDictionary(), new TempDataDictionary());
var vdcMock = new Mock<IViewDataContainer>();
var helper = new HtmlHelper(viewContext, vdcMock.Object);
string output = helper.UnorderedList(new int[] { , , });
Assert.AreEqual("<ul><li>0</li><li>1</li><li>2</li></ul>", output);
}
4-9行都是为实例化HtmlHelper做准备的。
四、参考
《Professional ASP.NET MVC 1.0》
《ProASP.NET MVCFramework》
http://msdn.microsoft.com/en-us/magazine/dd942838.aspx
http://www.henrycordes.nl/post/2008/02/MVC-Framework-and-Unit-Test.aspx
(转自作者:Lance 出处:http://www.cnblogs.com/nuaalfm/ )
asp.net 单元测试(转)的更多相关文章
- asp.net单元测试及查看代码覆盖率详细示例
		
在vs2008中创建单元测试 一,打开vs2008,创建一个类库VSTSDemo.因为我在学习的时候用的就是vs2008,其它版本的vs,方法应该差不多,大家自己研究吧 :) 删除掉默认生成的类,然后 ...
 - ASP.NET - 单元测试
		
Assert类的使用 Assert.Inconclusive() 表示一个未验证的测试: Assert.AreEqual() 测试指定的值是否相等,如果相等,则测试通过: AreSame() 用于验证 ...
 - VS2010(2012)中使用Unit Testing进行单元测试
		
原文 VS2010(2012)中使用Unit Testing进行单元测试 使用VS 2012自带的Unit Testing工具进行单元测试是非常方便的.网上关于这方面的例子很多,这篇随笔只起个人学习笔 ...
 - 使用IdleTest进行TDD单元测试驱动开发演练(3) 之 ASP.NET MVC
		
一.[前言] (1)本文将用到IOC框架Unity,可参照<Unity V3 初步使用 —— 为我的.NET项目从简单三层架构转到IOC做准备>(2)本文的解决方案是基于前述<使用I ...
 - ASP.NET 5 单元测试中使用依赖注入
		
相关博文:<ASP.NET 5 使用 TestServer 进行单元测试> 在上一篇博文中,主要说的是,使用 TestServer 对 ASP.NET 5 WebApi 进行单元测试,依赖 ...
 - ASP.NET 5 使用 TestServer 进行单元测试
		
之前如果对 ASP.NET WebAPI 进行单元测试(HttpClient 发起请求,并且可调试 WebAPI),一般采用 Owin 的方式,具体参考:<开发笔记:用 Owin Host 实现 ...
 - 单元测试 – ASP.NET MVC 4 系列
		
在开发可测试软件的过程中,单元测试已成为确保软件质量的一个不可或缺部分.测试驱动开发(Test-Driven Development,TDD)是编写单元测试的一种方法,采用该方法的开发人 ...
 - ASP.NET 系列:单元测试
		
单元测试可以有效的可以在编码.设计.调试到重构等多方面显著提升我们的工作效率和质量.github上可供参考和学习的各种开源项目众多,NopCommerce.Orchard等以及微软的asp.net m ...
 - 旅图beta版 asp.net web api 单元测试
		
旅图 beta版 asp.net web api 单元测试 测试接口:http://120.27.7.115:1010/Help 测试目的 对每个接口单元进行测试,保证每个接口的可靠性. 单元描述 注 ...
 
随机推荐
- 小 M 的算式(dfs)
			
[问题描述]小 M 在做数学作业的时候遇到了一个有趣的问题:有一个长度为 n 的数字串 S,小 M 需要在数字之间填入若干个“+”和恰好一个“=”,使其成为一个合法的等式.如对于 S=“2349”,可 ...
 - [Spring Boot]Request method 'GET' not supported
			
在网上查了些资料没有解决,检查代码发现 @PostMapping public String add(Employee employee){ System.out.println(employee); ...
 - 树状数组 P3605 [USACO17JAN]Promotion Counting晋升者计数
			
P3605 [USACO17JAN]Promotion Counting晋升者计数 题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 ...
 - java程序设计实验
			
建立文件调试jdk idea断点调试 项目素数的寻遍
 - .net mvc 框架实现后台管理系统
			
原文: https://www.cnblogs.com/ymnets/p/3424309.html -->底层实现 https://www.layui.com/ -->UI实现
 - poj3349找相同的雪花(哈希)
			
题目传送门 题目大意:给你n个雪花,每个雪花的六个棱都有各自的长度,如果存在两片雪花的每条棱长度对应相同,则输出一句英文,如果不存在就输出另外一句英文,n和长度都比较大. 思路:第一次真正接触哈希,查 ...
 - lvs 中DR模式负载均衡及keepalived
			
lvs DR配置 LVS负载均衡:三种负载均衡模式:DR,TUN(ip隧道),NAT,这里我们介绍DR模式 server1: 首先,配置server机yum源 方便后期实验流畅vim /etc/yum ...
 - ScheduledThreadPoolDemo01
			
package com.zhy.concurrency.timer; import java.util.Date; import java.util.Timer; import java.util.T ...
 - Spring Cloud  没移动完 到Ribbon
			
一 Spring Cloud各组件简要介绍 1. Eureka 注册中心. 帮助我们做服务的注册.服务的发现以及接口的调用 2. Ribbo 请求负载均衡 3. Zuul 网关.做合法性的校验. ...
 - /var 目录下文件系统
			
/var :日志文件/var/log:各种系统日志存放地*/var/log/message :系统信息默认日志文件 (非常重要)按周自动轮循/var/log/secure :记录登入系统信息文 ...