2012-05-12 40 views
6

我熟悉TDD的基本原則,是:當虛擬和實際實現都有接口時,單元測試的最佳方法是什麼?

  1. 編寫測試,這些都將失敗,因爲沒有實現
  2. 寫的基本實現使測試通過的
  3. 重構代碼

不過,我有點困惑,其中接口和實現契合。我創建在我的業餘時間一個Spring Web應用程序,而非在令人眩目的打算,我想知道我怎麼能測試接口/實現更好一點,拿我在這裏創建了這個簡單的例子代碼:

public class RunMe 
{ 

    public static void main(String[] args) 
    { 
     // Using a dummy service now, but would have a real implementation later (fetch from DB etc.) 
     UserService userService = new DummyUserService(); 
     System.out.println(userService.getUserById(1)); 
    } 
} 

interface UserService 
{ 
    public String getUserById(Integer id); 
} 

class DummyUserService implements UserService 
{ 
    @Override 
    public String getUserById(Integer id) 
    { 
     return "James"; 
    } 
} 

我創建了UserService界面,最終會出現這種實際的實現,將查詢數據庫,但爲了獲取應用程序掉在地上,我取代的DummyUserService實現,只返回現在有一些靜態數據。

問:我怎樣才能爲實現上述測試策略?

我可以創建一個名爲DummyUserServiceTest和測試,當我打電話getUserById()它會返回James測試類,看起來很簡單,如果不是浪費時間(?)。

隨後,我還可以創建一個測試類RealUserService,測試getUserById()從數據庫返回用戶名。這是混淆了我咯,這樣做的部分,這難道不是本質上超越單元測試的邊界,變得更加的一體化試驗(與數據庫命中)的?

問題(改進了一點):當使用虛擬/樁樁接口和實際實現時,哪些部分應該進行單元測試,哪些部分可以安全地保持未測試?

我花了幾個小時,昨晚在這個題目谷歌搜索,而且大多發現任何教程,什麼是TDD,或者如何使用JUnit的例子,但在沒有什麼建議應實際測試的領域。這完全有可能,但我沒有足夠努力地搜索或者沒有找到正確的東西...

回答

4

不要測試虛假實現:它們不會用於生產。測試它們沒有任何意義。

如果真正實施UserService並沒有別的比去一個數據庫,並通過ID獲取用戶名,那麼測試應該測試它確實是正確做的。如果你願意,可以稱之爲集成測試,但它仍然是一個應該被編寫和自動化的測試。

通常的策略是在測試的@Before註釋方法中用最少的測試數據填充數據庫,並且測試方法檢查是否存在數據庫中的ID,返回相應的用戶名。

0

JB的回答是一個很好的,我想我會扔了我使用的另一種技術。

當開發原始測試時,不要打擾第一個地方去掉UserService。事實上,繼續寫下真實的東西。繼續執行以下步驟Kent Beck's 3 rules

1)讓它工作。 2)說得對。 3)快速。

你的代碼將有測試,然後驗證通過ID查找作品。正如JB所述,此時您的測試將被視爲集成測試。一旦他們通過,我們已經成功實現了第1步。現在,看看設計。這樣對嗎?調整任何設計的氣味,並檢查你的列表中的第2步。

對於第3步,我們需要快速進行此測試。我們都知道集成測試對於所有事務管理和數據庫設置都很慢並且容易出錯。一旦我們知道代碼有效,我通常不會爲集成測試而煩惱。正是在這個時候你可以引入你的虛擬服務,有效地將你的集成測試變成一個單元測試。既然它沒有以任何方式觸及數據庫,我們可以從列表中檢查第3步,因爲這個測試現在很快。

那麼,這種方法有什麼問題?那麼很多人會說我仍然需要測試數據庫支持的UserService。我通常不會在我的項目中進行集成測試。我的觀點是,這些類型的測試是緩慢,脆弱的,並且在大多數項目中沒有足夠的邏輯錯誤來爲自己支付。

希望有幫助!

布蘭登

3

我建議你先閱讀這本書:Growing Object-Oriented Software Guided by Tests由史蒂夫Freemand和NAT普賴斯。它回答了你的問題和許多與TDD相關的問題。

在您的具體情況下,您應該使RealUserService可配置一個數據庫適配器,這將使真正的數據庫查詢。服務本身將服務,而不是數據持久性。閱讀這本書,它會有很大幫助:)

相關問題