IMZRH的日志

努力成为一个有用的人

导航

使用NUnit对数据库操作进行单元测试

Posted on 2009-03-23 17:46  张荣华  阅读(2065)  评论(1编辑  收藏  举报

环境:VS2005 , Nunit2.4 sql server 2005


第一步:首先建立一个新工程AccountTest
第二步:为此专案添加EnterpriseServices组件。当然作单元测试,也应该添加上NUnit框架


第三步:编写测试基础类

using System;
using System.Collections.Generic;
using System.Text;
using System.EnterpriseServices;
using NUnit.Framework;
using System.Runtime.InteropServices;
using System.Data.SqlClient;
namespace Bank
{
/// 
/// 這是一個測試各種单元测试的基礎類,所有的要操作數據庫的測試類都從它繼承
/// 這樣就能保證所有的測試操作無論是新增、修改、刪除都能順利測試成功,但是并吧產生任何垃圾數據
/// 也不會修改任何實際運行的數據庫
/// 
[Transaction(TransactionOption.Required)]
[TestFixture]
public class DatabaseFixture : ServicedComponent
{
protected SqlConnection Connect = null;
/// 
/// 构造函数
/// 
public DatabaseFixture()
{
}
/// 
/// 本属性标识此测试方法结束后调用,所有事务的撤销工作都是由它来实现的
/// 
[TearDown]
public void TransactionTearDown()
{
if (ContextUtil.IsInTransaction)
{
ContextUtil.SetAbort();
}
}
/// 
/// 我在这里建立了数据库链接,其实不建立也行
/// 
[SetUp]
public void SetFirst()
{
try
{
Connect = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;User ID=sa;Initial Catalog=NorthWind;Data Source=127.0.0.1");
Connect.Open();
}
catch (Exception ex)
{
}
}
}
}

第四步: 创建签名Key

调用命令行程序(路径=系统盘:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\) sn.exe -k mytest.snk
然后把创建好的mytest.snk加入的工程中。设置参见下图(选中工程右键--Properties--Signning)


第五步:创建单元测试文件(代码如下)

using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.Data;
using System.Data.SqlClient;
namespace Bank
{
[TestFixture]
public class DataTest: DatabaseFixture
{
/// 
/// 这个就是我建立的测试方法,大家发现反复执行,也不会实际把数据新增到数据库中
/// 
[Test]
public void InsertTest()
{
string SQL = "insert Categories(CategoryName, Description) values('测试类型', '测试类型描述')";
Assert.IsTrue(ExecSQLNoQuery(SQL));     //如果新增失败这行代码测试无法通过
//执行查询,看是否真的新增到数据库
DataSet ds = QueryResult("select * from Categories where CategoryName='测试类型'");
//下面两句可以测试是否真的添加到了数据库
Assert.IsNotNull(ds);
Assert.AreEqual(1, ds.Tables[0].Rows.Count);
//测试新增的数据和是否正确
StringAssert.IsMatch("测试类型描述FF", ds.Tables[0].Rows[0]["Description"].ToString());
}
/// 
/// 执行没有返回结果的SQL语句
/// 
protected bool ExecSQLNoQuery(string SQL)
{
SqlCommand Command = new SqlCommand();
Command.Connection = Connect;
Command.CommandType = CommandType.Text;
Command.CommandText = SQL;
bool retFlag = false;
try
{
Command.ExecuteNonQuery();
retFlag = true;
}
catch (Exception ex)
{
}
finally
{
Command.Dispose();
}
return retFlag;
}
/// 
/// 提供SQL语句返回查询结果
/// 
protected DataSet QueryResult(String SQL)
{
SqlCommand Command = new SqlCommand();
Command.Connection = Connect;
Command.CommandType = CommandType.Text;
Command.CommandText = SQL;
SqlDataAdapter Adapter = new SqlDataAdapter(Command);
DataSet ds = new DataSet();
bool retFlag = false;
try
{
Adapter.Fill(ds);
retFlag = true;
}
catch (Exception ex)
{
}
finally
{
Adapter.Dispose();
Command.Dispose();
}
return retFlag == true ? ds : null;
}
}
}

第六步:编译成功,进行测试。
        你可以在选中工程右键--Properties--debug--start external program选中UNit程序(这种情况可以进入调试状态跟踪运行),你也可以直接执行UNit测试程序加载刚才编译的dll进行测试。
        错误出现了如下图,这个错误捆扰了好一天多的时间,主要是由于在2005下以前也没有使用过EnterpriseServices的经验。
        我一开始怀疑是不是网上的例子是不是本身有问题呢,我是按照例子亦步亦趋的做的,唯一的区别就是vs003和vs005的区别,最后我在Vs2003下试验了一下,能正常通过。我想要么是VS2005组件有更新,调用模式有区别,或是2005环境要有的工程设置要做变更。我查了许多资料,并仔细分享错误,其中有这么一个提示《而且符合所有其他 ComVisibility 需求》引起了我的注意,因为我发现Assemblyinfo.cs文件中有[assembly: ComVisible(false)]一行代码,于是我修改为[assembly: ComVisible(true)],编译运行测试结果。哈哈,终于看到我梦寐以求的如下界面了。

本来到这里我本以为大功告成了,结果后面的错误又让我焦头烂额了。
新问题:由于这个是测试的研究例子,我开始实际实施到我正在进行的项目中。结果运行又出现了新错误。我调试发现进行数据库链接的时候出现“已停用分散式交易管理員 (MSDTC) 的網路存取。請使用元件服務系統管理工具啟用 DTC,以使用 MSDTC 安全性設定中的網路存取”后来发现是本机的MSDTC服务的问题,我的是XP系统。设置步骤如下。
1)进入控制面板--系统管理工具--组件服务。点击我的电脑--属性--MSDTC--安全性设定,如下图

我一口气钩了许多我认为相关的选项,大家可以看到我上面的设置。
在后来的编译中我还发现的类似一些错误,我就不一一详细描述了,不过我把上面没有提到的错误的解决方案列举如下 :
1:  MSDTC on server 'ITEC-KS-CCNET' is unavailable. 为远端MSDTC没有启动,在组件服务中可以启动。
2:  Window2003下,MSDTC并没有缺省安装,还需要手工安装一下,方法是新增删除程序中,点击新增组件,然后选中Application Servers 点击详细资料,然后选中启用网络DTC存取,保存安装即可。当然安装后也要进入组件服务设置一下MSDTC的安全性设定。
3:  还有一个错误是您必須具備系統管理認證才能執行此工作。請連絡您的系統管理員以尋求協助。最后我发现是数据库服务器和运行此测试程序的机器根本不在一个网段,相互COM+组件无法互相访问,因为我用Telnet测试对方135,139端口根本不能通讯,因此需要开启此两个端口打开DCOM服务才可以。
我想经过上面的这写设置,你一定会看到你数据库单元测试的绿色通过条。