当单元测试需要对数据库执行CRUD(Create,Retrieve,Update,Delete)操作时,测试过后会在我们的数据库中留下大量重复的垃圾数据,这些垃圾很碍眼不是吗?而且我们的下一个测试有可能因为这些垃圾产生一些错误。

那么我们要如何处理这些垃圾数据和保证测试的稳定的呢?显然,我们需要在每次测试之前和测试完成之后让数据库都保持相同的状态。换句话说,就是我们需要"undo"这些在测试中对数据库执行的CRUD操作。

对于我们需要的这种"undo"操作,你以前是怎么做的呢?手动的移除还是使用ADO.NET的事物处理呢?这些方法都可行,但对我们来说还不够好。因为它们都需要我们编写更多的代码,影响我们的开发效率。

现在,就要开始说本文的重点了,利用COM+的自动事务处理功能来帮助我们实现我们的"undo"。

首先,写一个基类,此类能够在每一个方法完成后自动回滚对数据库的操作:

using System;
using NUnit.Framework;
using System.EnterpriseServices;

namespace TransactionTest
{
    [TestFixture]
    [Transaction(TransactionOption.Required)]
    public class DatabaseFixture:ServicedComponent
    {
        [TearDown]
        public void TransactionTearDown()
        {
            if(ContextUtil.IsInTransaction)
            {
                ContextUtil.SetAbort();
            }
        }
    }
}

下面再写一个使用此基类的示例程序:

using System;
using NUnit.Framework;
using System.Data;
using System.Data.SqlClient;

namespace TransactionTest
{
    public class CategoryTests:DatabaseFixture
    {
        string CONN = @"Server=192.168.0.58\sun;Database=Northwind;uid=帐号;pwd=密码";

        [Test]
        public void InsertTest()
        {
            string categoryName = Insert("Test category");
            VerifyRowExists(categoryName, true);
        }

        [Test]
        public void DeleteTest()
        {
            string categoryName = Insert("Test category");
            Delete(categoryName);
            VerifyRowExists(categoryName, false);
        }

        /**//// <summary>
        /// 新增一条记录
        /// </summary>
        /// <param name="categoryName"></param>
        /// <returns></returns>
        private string Insert(string categoryName)
        {
            using (SqlConnection conn = new SqlConnection(CONN))
            {
                string strSQL = "Insert Categories (CategoryName) values('" + categoryName + "')";
                SqlCommand cmd = new SqlCommand(strSQL, conn);
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            return categoryName;
        }

        /**//// <summary>
        /// 删除一条记录
        /// </summary>
        /// <param name="categoryName"></param>
        /// <returns></returns>
        private string Delete(string categoryName)
        {
            using (SqlConnection conn = new SqlConnection(CONN))
            {
                string strSQL = "Delete from Categories Where CategoryName='" + categoryName + "'";
                SqlCommand cmd = new SqlCommand(strSQL, conn);
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            return categoryName;
        }

        /**//// <summary>
        /// 对执行的数据库操作进行验证
        /// </summary>
        /// <param name="categoryName"></param>
        /// <param name="shouldExist"></param>
        private void VerifyRowExists(string categoryName,bool shouldExist)
        {
            SqlConnection conn = new SqlConnection(CONN);
            conn.Open();

            string strSQL = "Select * from Categories where CategoryName='" + categoryName + "'";
            SqlCommand cmd = new SqlCommand(strSQL, conn);
            SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
            Assert.AreEqual(shouldExist,dr.HasRows);
            dr.Close();
        }
    }
}

如果编译上面的程序,还需要给程序加一个强名称,否则是无法通过的

在命令行使用 sn -k test.snk
然后把 test.snk 拷贝到程序目录中,再设置
[assembly: AssemblyKeyFile(@"..\..\..\test.snk")]

原文:http://weblogs.asp.net/rosherove/articles/dbunittesting.aspx

转载于:https://www.cnblogs.com/netflu/archive/2005/07/29/202805.html

利用COM+对数据库操作进行单元测试相关推荐

  1. Android开发笔记(一百七十五)利用Room简化数据库操作

    虽然Android提供了数据库帮助器,但是开发者在进行数据库编程时仍有诸多不便,比如每次增加一张新表,开发者都得手工实现以下代码逻辑: 1.重写数据库帮助器的onCreate方法,添加该表的建表语句: ...

  2. nodeJS下利用mongdb进行数据库操作

    2019独角兽企业重金招聘Python工程师标准>>> 需要引用的node_modules npm install mongodb 此处引用的mongodb模块版本为1.4.12 一 ...

  3. 利用Java存储过程简化数据库操作

       利用Java存储过程沟通SQL.XML.Java.J2EE和Web服务. 存储过程(stored procedure)允许将运行于数据库层中的持久性逻辑与运行于中间层中的商务逻辑有效地分离开来. ...

  4. 利用对象池优化数据库操作

    简介:这是利用对象池优化数据库操作的详细页面,介绍了和asp.net,.Net,创建,对象池,示例有关的知识,要查看更多相关信息,请点击此处 说到对象池,大家都不陌生.很多人都实现过,网上的代码也满天 ...

  5. 玩转JDBC打造数据库操作万能工具类JDBCUtil,加入了高效的数据库连接池,利用了参数绑定有效防止SQL注入

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53750584 本文出自[DylanAndroid的博客] 玩转JDBC打造数据 ...

  6. Junit-对涉及数据库操作的服务进行单元测试

    之前一直不知道怎么通过单元测试,对涉及数据库操作的服务进行验证,现在了解了,做个记录. ******************************************************** ...

  7. Android之单元测试及数据库操作,android的单元测试

    1.新建android Test project 2. 选择针对测试的项目 3.新建类继承AndroidTestCase即可: package com.howlaa.sms.test; import ...

  8. scala利用akka框架封装数据库操作api微服项目

    原作:https://blog.csdn.net/weixin_42003671/article/details/97630151 原作很详细了但是基本都是test阶段的东西,也踩了很多坑才走出来 这 ...

  9. 实验六JDBC数据库操作_JAVA

    实验目的: 1.熟悉数据库基本操作 2.掌握利用JDBC进行数据库的连接 3.利用语句对象Statement和PreparedStatement对表.记录.列进行增.删.改.查等操作 4.将数据库操作 ...

最新文章

  1. java url特殊字符处理_简单实例处理url特殊符号处理(2种方法)
  2. 如何获取独立项目开发经验
  3. const定义常量_go语言基本语法——常量constant
  4. 基于虚拟日志压缩的数据同步方案
  5. java调c 申请内存_JAVA简单调用C/C++语言(JNI学习三)
  6. python操作本地数据库,Python基础篇-Python连接Mysql操作数据库
  7. bootdo框架切换tab标签时自动刷新,无需手动刷新
  8. CSS样式--前端布局(五)
  9. java 同比环比_数据相关概念同比,环比
  10. 2019年任正非给全体华为员工的信
  11. 手绘几何图形识别(下)
  12. python爬虫练习--爬上海法院开庭公告信息
  13. python泰勒公式计算e的x次方_e的x次方在x0=0的泰勒展开式
  14. Linux进程的后台运行
  15. 人脸识别IU(李知恩)(2)
  16. JetBrains教育账户注册问题
  17. js传参数受特殊字符影响错误
  18. 供应商管理库存(VMI)的意义与实际操作
  19. php 对密码加密解密(官方推荐)
  20. 3DMAX三维制作地形图教程

热门文章

  1. JVM面试问题系列:JVM 配置常用参数和常用 GC 调优策略
  2. 移动互联环境下的流程管理
  3. 数据库:数据库死机和掉电时如何让恢复数据
  4. MYSQL:HAVING
  5. 全面总结:进程与线程
  6. Android——怎么在一个 Activity 中销毁另外一个 Activity
  7. C语言 输入一个正整数n,再输入n个字符,如果是小写字符就将其转换为大写字符,如果是大写字符就 转换为小写字符
  8. Null return value from advice does not match primitive return type for: public abstract boolean
  9. 联想电脑怎么进入Android,联想电脑怎么连接手机
  10. 为什么说数据中心是5G最大的受益者?