最近在看.net单元测试艺术,我也喜欢单元测试,今天介绍一下如何测试异常、如何测试返回值、如何测试模拟对象的参数传递、如何测试数据库访问代码。单元测试框架使用的是NUnit,模拟框架使用的是:Rhino.Mocks。

1.测试异常,可以直接对方法进行异常测试,也可以对模拟对象进行异常测试,但是,对模拟对象进行异常测试,很少用,所以,这里就介绍对方法的异常测试。请看如下代码,当用户名为空的时候,抛出异常。

     public bool Valid(string userName, string passWord)
{
if (string.IsNullOrEmpty(userName)) throw new ArgumentNullException("userName is null"); var isValid = userName == "admin" && passWord == "123456"; Log.Write(userName); return isValid;
}

测试代码如下:

      [Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Vaild_Throw_Test()
{
MyLogin l = new MyLogin(); l.Valid("", "123456");
}

这里需要特性“ExpectedException”,意思是期待抛出一个异常。这里不需要再进行断言了,抛出异常后,后面的代码也就不会执行了。

2.测试返回值,这里主要讲测试模拟对象的返回值。这里用到了一个LastCall的一个类,比较常用,一些辅助测试的功能,都在该类中。测试代码如下:

        [Test]
public void Valid_Return()
{
MockRepository mock = new MockRepository(); var log = mock.DynamicMock<ILog>(); using (mock.Record())
{
log.WriteLog("admin");
LastCall.Return(0);
}
        var returnValue = log.WriteLog("admin");         Assert.AreEqual(returnValue, 0);
}  

3.测试模拟对象的参数传递,当调用模拟对象时,可能需要传递参数,如果参数的值不一至时,会导致测试失败,比如:我需要传递一个字符串,其中包含了一个GUID+UserName,这里GUID可能我们无法模拟,所以,测试参数时,只需要测试UserName就可以。

方法代码如下:

    public bool Valid_Paramter(string userName, string passWord)
{
Log.Write(Guid.NewGuid() + userName); return userName == "admin" && passWord == "123456";
}

测试代码如下:

       [Test]
public void Valid_Paramter()
{
MockRepository mock = new MockRepository(); var log = mock.DynamicMock<ILog>(); using (mock.Record())
{
log.Write("admin"); LastCall.Constraints(Rhino.Mocks.Constraints.Text.Contains("admin"));
}
       //这里代码如果不明白,可以看上一节,里面有说明。
MyLogin login = new MyLogin(); login.Log = log; var valid = login.Valid_Paramter("admin", "123456"); Assert.AreEqual(valid, true); mock.VerifyAll();
}

  这里只是测试模拟对象的参数传递。

4.测试数据库访问代码,这里提供的方法是,执行完测试代码后,对数据库进行回滚。有两种实现方式,一种是使用Rollback特性,一种是使用TransactionScope类。其实,Rollback也使用TransactionScope类。

  1)   Rollback特性

  开始我以为Rollback是NUnit框架自带的一个特性,结果不是,需要自己编写代码,这里需要继承ITestAction接口,该接口包含BeforeTest方法和AfterTest方法。Rollback特性的代码如下:

  public class RollbackAttribute : Attribute, ITestAction
{
private TransactionScope transaction; public void BeforeTest(TestDetails testDetails)
{
transaction = new TransactionScope();
} public void AfterTest(TestDetails testDetails)
{
transaction.Dispose();
} public ActionTargets Targets
{
get { return ActionTargets.Test; }
}
}

  下面是被测试的代码,这里我用了EF框架,代码非常简单,向TitleInfo表中,写入数据,该表中只有一个字段,就是title字段。如果写入成功,则返回值大于0.

   public int Insert(string title)
{
testEntities db = new testEntities(); var titleInfo = new TitleInfo()
{
Title = title
}; db.TitleInfo.Add(titleInfo); return db.SaveChanges();
}

  使用Rollback特性进行测试。

        [Test]
[Rollback]
public void Test_Insert()
{
DBLibrary db = new DBLibrary(); var count = db.Insert("admin"); Assert.True(count > 0);
}

   非常简单,加入Rollback特性即可,这里不会向数据库写入记录,但是测试会成功。

  2)   使用TransactionScope类测试数据访问层,该类可以实现数据库的事务操作,执行测试代码后,会对数据库的事务进行回滚,达到测试的目的,而不需要修改数据库的数据。测试代码如下:

    [TestFixture]
class DBLibraryTest
{
TransactionScope socp; [SetUp]
public void Init()
{
socp = new TransactionScope();
} [TearDown]
public void Close()
{
socp.Dispose();
} [Test]
public void Test_Insert()
{
DBLibrary db = new DBLibrary(); var count = db.Insert("admin"); Assert.True(count > 0);
}
}

  这里加入了TransactionScope类,在Test_Insert方法执行前,会先执行Init方法,执行完Test_Insert方法后,执行Close方法,对事务进行回滚。其实Rollback只是对TransactionScope进行了封装,通过NUnit框架,很方便的实现了数据库事务的回滚。

总结:这里只是总结了常用的测试方法,如果大家还有其它的常见方法,可以分享一下,大家共同学习。

.net单元测试——常用测试方式(异常模拟、返回值测试、参数测试、数据库访问代码测试)的更多相关文章

  1. atitit.架构设计---方法调用结果使用异常还是返回值

    atitit.架构设计---方法调用结果使用异常还是返回值 1. 应该返回BOOL类型还是异常 1 2. 最终会有四种状况,抛出异常.返回特殊值.阻塞.超时 1 3. 异常的优缺点点 1 4. jav ...

  2. android两种方式获取AsyncTask返回值

    获取AsyncTask返回值,在Activity中使用. 引用链接:https://www.oschina.net/code/snippet_725438_49858#72630 [1].[代码] [ ...

  3. 使用jquery通过AJAX请求方式,后台返回了当前整个HTML页面代码

    该结果分为多种情况: 1.当前项目使用了interceptor/filter,拦截或者过滤了特定请求. 2.在HTML页面使用了表单提交,没有对表单的“onsubmit”事件做return false ...

  4. VS2012 Unit Test(Void, Action, Func) —— 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试

    [提示] 1. 阅读文本前希望您具备如下知识:了解单元测试,了解Dynamic,熟悉泛型(协变与逆变)和Lambda,熟悉.NET Framework提供的 Action与Func委托.2.如果您对单 ...

  5. 对无返回值、使用Action或Func作为参数、多重载的方法进行单元测试

    VS2012 Unit Test(Void, Action, Func) —— 对无返回值.使用Action或Func作为参数.多重载的方法进行单元测试 [提示] 1. 阅读文本前希望您具备如下知识: ...

  6. mock.js中新增测试接口无效,返回404

    项目是使用的npm+vue+mock模拟数据 我碰到的是在mock配置文件中新增接口,但是接口在测试时无效,返回404.但是在前端代码中把新接口换成配置文件中之前就有的,然后测试就正常了. 所以按问题 ...

  7. 只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

    ## 统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生. 比较通用的返回值格式如下: ```jav ...

  8. easyui 表单和自定义验证扩展和js自定义返回值

    ================jsp==========================<form  method="post" id="regfrminp&qu ...

  9. MyBatis查询结果resultType返回值类型详细介绍

    一.返回一般数据类型 比如要根据 id 属性获得数据库中的某个字段值. mapper 接口: // 根据 id 获得数据库中的 username 字段的值 String getEmpNameById( ...

随机推荐

  1. Android 窗口管理

    一.概述 在Android系统中,从设计的角度来看,窗口管理系统是基于C/S模式的.整个窗口系统分为服务端和客户端两大部分,客户端负责请求创建窗口和使用窗口,服务端完成窗口的维护,窗口显示等. 在Cl ...

  2. CentOS6.5 x86_64 配置Broadcom 43XX系列 无线网卡驱动

    from: http://wiki.centos.org/HowTos/Laptops/Wireless/Broadcom?action=show In order to install Broadc ...

  3. MVC3 IIS7部署记录

    环境 系统:Win7 IIS:IIS7 开发工具:VS2010 MVC版本:ASP.NET MVC 3.0 注意 1.在部署MVC应用之前,一定要确保你的程序BIN文件夹下面是否包含 System.W ...

  4. Windows SharePoint Services 3.0编码开发工具和技巧(Part 1 of 2)

    转:http://blog.csdn.net/mattwin/article/details/2074984 WSSv3 Technical Articles_Windows SharePoint S ...

  5. ASP.NET使用EasyUI-DataGrid + ashx + JQuery Ajax:实现数据的增删查改,查询和分页!

    转自:http://www.cnblogs.com/lt-style/p/3457399.html 数据表: 学生表:学生编号.姓名.性别.班级编号.年龄 班级表:班级编号.班级名称 开发过程: 1. ...

  6. 如何将数据库中已有表导入到powerDesigner生成pdm文件

    1.create new PDM: 2.select database menu; 3.click Reverse  Engineer database :4.then choose your scr ...

  7. 使用VisualStudio进行单元测试之二

    借着工作忙的借口,偷了两天懒,今天继续单元测试之旅.前面说了如何进行一个最简单的单元测试,这次呢就跟大家一起来熟悉一下,在visual studio中如何进行数据驱动的单元测试. 开始之前先来明确一下 ...

  8. Qt学习之路(1)------Qt常用类用法说明

    Qt常用类 向控制台输出文本 第一个例子,我们采用STL的方式: console.cpp #include <iostream> int main() { std::cout <&l ...

  9. ListControl常用操作汇总

    本文根据本人在项目中的应用,来谈谈CListCtrl的部分用法及技巧.当初学习时,查了很多资料,零零碎碎的作了些记录,现在主要是来做个总结,方便以后查阅.主要包括以下十三点内容:基本操作.获取选中行的 ...

  10. JavaScript高级程序设计46.pdf

    鼠标按钮 只有在主鼠标按钮被单击(或键盘回车键被按下)是才会触发click事件,对于mousedown和mouseup事件,其event对象存在一个button属性,表示按下或者释放按钮.DOM的bu ...