2009-09-21 98 views
3

我最近得到了一個任務來創建一個簡單的實用程序,允許從具有特殊格式的文件導入數據到數據庫。我用少數類實現了控制檯應用程序(程序類與業務邏輯類一起運行,而業務邏輯類又與數據訪問類一起運行)。一切正常,但現在我正在考慮創建一些單元測試和重構應用程序(我之前沒有創建真正的單元測試,很久以前只是一堆集成測試,所以我相信這個應用程序是練習的完美領域) 。數據訪問,單元測試,依賴注入

所以,這裏是一個問題:數據訪問類已經變爲靜態的,這不允許模擬它,並因此創建真正的單元測試。爲了解決這個問題,我需要創建一個接口並在數據訪問類中實現它。此外,我將不得不向業務邏輯類添加一個構造函數,該類將接受該接口類型的參數。所以這意味着我最終會在應用程序的Main()方法中創建數據訪問類,並且告訴我這不是最好的方法(入口點應該知道某些數據訪問的事情是真的嗎?如果鏈是更長或應該有幾個鏈?)。我知道我可以使用一些IoC容器,但我認爲這是使用容器過於簡單的應用程序。

謝謝!

回答

5

我需要創建一個接口和數據訪問類實現它。此外,我將不得不添加一個構造函數 到業務邏輯類,將 接受該接口 類型的參數。因此,這意味着我將結束 在 應用Main()方法創建數據訪問類和 東西告訴我這不是最好的 方法(是不是真的OK了 切入點應該瞭解一些 數據訪問的東西什麼?如果鏈 要長得多還是應該有 幾個連鎖店?)

相反!這個最好的方法,至少從可測試性的角度來看。

使您的業務邏輯層可測試的唯一方法是通過完成您正在考慮的內容來將其與數據訪問層隔離。

您的頂層應用程序是buck停止的地方 - 它是唯一需要知道具體數據訪問類是什麼的組件。

如果鏈條長得多或有多條鏈,這沒什麼大不了的(儘管如果它失控時可能需要考慮摺疊某些應用程序層)。考慮這種潛在的代碼Model-View-Presenter應用程序的View,其中Presenter有一個CustomerService的依賴,這對一個AccountingServiceRepository的依賴和依賴(這也是依賴於Repository):

public CustomerView() { 
    IRespository  repository  = new ConcreteRepository(); 
    IAccountingService accountingService = new ConcreteAccountingService(repository); 
    ICustomerService customerService = new ConcreteCustomerService(accountingService, repository) 
    this._Presenter = new CustomerPresenter(customerService); 
} 

最後,如果你不想使用依賴注入容器(儘管其中有些是令人驚訝的輕量級),那麼就不需要使用依賴注入容器 - 手工依賴注入可以正常工作,直到你開始在整個地方重複自己(或者你想要配置運行時的依賴關係)。

+0

+1:很好的答案!我特別喜歡「降價停止線」。對DI容器也有好評! – TrueWill 2009-09-21 17:38:15

+0

@Jeff - 謝謝,我會試試看。雖然我悲觀的存在告訴我應該有一些隱藏的陷阱:) – Dev 2009-09-21 18:18:52

+0

@Dev:懷疑主義是靠近敬虔! ;) – 2009-09-21 18:20:41

0

這裏有一個簡單的解決方案:

public void insert (...) { 
     DataAccess.insert (...); 
    } 

現在,您可以覆蓋這些調用:與其說你直接數據訪問類,使用輔助方法的。我建議拆分測試,像這樣:

  1. 創建幾個測試它確保DataAccess做時,它得到正確的參數正確的事情。

  2. 在樣機測試中,只需收集發送到insert()的參數即可。根本不要撥打DataAccess

在#1測試將確保將數據寫入到數據庫將工作,而在#2測試將確保您撥打DataAccess用正確的價值觀。後面的測試會很快運行,這將使測試特殊情況變得很容易,等等。

您不需要一直運行#1的測試。只有在DataAccess或發佈之前更改了某些內容。這將使測試高效愉快。

+0

添加評論爲答覆,沒有太多空間 – Dev 2009-09-21 15:59:39

+0

@Dev - 用答案回答可能很快就會令人困惑。最終答案將被重新排序,亞倫可能會改變他的名字,或者他甚至可能會刪除他的答案。我建議在評論中回答 - 如果您需要比分配的角色更多的空間,則可以在兩條評論中分發回覆。或者,如果您認爲它可以幫助人們回答您,您可以編輯原始問題以包含一些信息。 – 2009-09-21 16:53:18

+0

謝謝傑夫,將移動那個評論「回答」。 – Dev 2009-09-21 16:57:29

1

假設您正在使用LINQ to SQL,也許您可​​以使用存儲庫模式將DataContext包裝到您稍後可以模擬的接口中,從而使單元測試成爲可能。

有大約在互聯網這個問題的一些文章,這裏是一個: http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx

+0

現在我正在使用帶有自定義方法的類型化數據集從文件讀取並寫入文件。我最初並沒有使用實體框架或linq2sql,因爲當時我不得不編寫這個應用程序,我沒有太多時間用我沒有經歷過的技術進行實驗。但這是個好主意,也許我會重寫我的DAL。 – Dev 2009-09-21 15:32:12