本文是根據 Roy Osherove的《Simplified Database Unit testing using Enterprise Services 》一文的整理而來,源地址如下: http://weblogs.asp.net/rosherove/articles/dbunittesting.aspx
一、主題
通過介紹一種在.Net平台上、基於Enterprise Services、NUnit針對資料訪問層的單元測試方法,瞭解與掌握該測試方法的優劣和具體實施方法。
隨著軟體工程、軟體設計技術的發展及實際軟體項目或產品的需要,測試技術中的測試載入器和方法發生了翻天覆地的變化。出現了測試驅動開發(Test Driven Development ),即將測試方案設計工作提前,在編寫代碼之前先做這一項工作; 從測試的角度來驗證設計,推導設計; 同時將測試方案當作行為的準繩,有效地利用其檢驗代碼編寫的每一步,即時驗證其正確性,實現軟體開發過程的“小步快走“。
在這個思想下,單元測試是TDD的源泉。本篇文章就是對針對資料訪問層測試(Data Access Layer)的一種單元測試方法。
二、常見資料訪問層的單元測試方法介紹:
資料訪問層一般都是在單個類中存在大量的CRUD(Create, Retrieve, Update, Delete) 方法,一般的測試方法,會帶來如下的各種問題。主要有:
1、垃圾資料;2、影響其他的測試;3、會從不知到的狀況開始測試。
處理以上問題的常見方法: 1、在測試代碼中Undo你的CRUD方法。 2、手工刪除(最普遍的方法):這樣做會在每個測試案例結束時,加入於你的測試相反的操作方法。該方法會帶來如下問題:a、相反的操作方法沒有現成的方法(需要你自己寫預存程序或ADO.Net類);b、寫的刪除方法不能完全保證其是否有BUG; c、方法可能會破壞資料的完整性(資料關係不對,資料全部刪除了)。
3、利用ADO.Net中的事務對象實現:在每個測試中利用事務及復原處理你的每個資料操作。該方法會帶來如下問題:a、你需要擔心你的測試案例中的事務對象對被測試的方法中包含的內部事務的影響。(利用命令模式可以解決這個問題,見James Newkirk 著作《Test Drivern Development with Micrsoft.Net》)包含很多的交易管理類 )。
三、COM+ Enterprise Services 測試資料訪問層
為瞭解決這些缺點我們的解決方式是利用COM+ Enterprise Services 來測試資料訪問層。
首先,利用System.Enterprise Services 及NUnit編寫測試案例的基類如下:
namespace TransactionTesting {
[TestFixture]
[Transaction(TransactionOption.Required)]
public class DatabaseFixture:ServicedComponent
{
[TearDown]
public void TransactionTearDown(){
if(ContextUtil.IsInTransaction){
ContextUtil.SetAbort();} }
} }
以上代碼的解釋如下: 1、基類繼承於TransactionOption.Required(它利用了COM+的自動交易處理)
2、用[TestFixture]與Transaction(TransactionOption.Required)]兩個屬性,能使這個類的初始化及調用時,COM+將自動化創造一個事務內容物件,並加入已存在的事務列表中。
3、在TearDown方法中調用ContextUtil.SetAbort()。
4、
注意測試專案必須有一個強式名稱。
以上操作後,會發生:
1、在每個測試前,事務內容物件開啟,並把測試類別加入到已存在的事務中;
2、測試被執行;
3、測試結束時,TearDown方法被執行,事務被復原。
其次,設定強式名稱。
用SN.exe –K 建立密碼檔案,在測試專案中開啟AssemblyInfo.cs 設定屬性[assembly: AssemblyKeyFile(@"../../../test.snk")] ;設定靜態Version屬性 ,修改“1.0.*”為[assembly: AssemblyVersion("1.0.0")] 。
然後,編寫測試代碼
測試類別需要繼承上面編寫的DatabaseFixture,其他的測試方法按照NUnit規定的編寫即可。
四、該方法的缺陷 1、需要ADO.Net驅動支援分布式的事務(如對MS- Acess不支援)
2、被測試的方法本身利用了Enterprise Services,並設定了Transaction attribute (“Disabled”、 “Not Supported”、 "Requires New")。 3、被測試的方法本身有不參與分散式交易的DDL語句(用語定義和管理資料庫中的對象,如Create,Alter和Drop,因為DDL操作是隱性提交的不能Rollback )。