2013-04-10 78 views
4

在接受記者採訪時,有人問我這個問題:「你怎麼做代碼很難進行單元測試?」最後我喃喃自語的東西寫一個緊密耦合的代碼。任何人都可以告訴我什麼是這個問題的正確答案/方法?編寫代碼,這是很難進行單元測試

回答

4

看看Mishko的Guide: Writing Testable Code,將許多這些缺陷介紹到您的代碼中,最終會得到無法測試的代碼。

例如:

  • 做盡可能多,你可以在構造函數中,通過創建到處方法的長鏈調用
  • 使用的單身啓動線程,使用循環和IFS得墨忒耳
  • 破法,他求的依賴,看看他們在靜態提供商
  • 與2k行的代碼創建全能類
+0

米斯科的博客是一個救世主!我分享了相同的鏈接;) – 2013-04-10 05:25:26

+0

我不同意2K行代碼點。 – 2013-04-10 05:27:24

+1

2K是上帝級的?那麼我該怎麼處理15K +的課程 - 是那些宇宙課程? – dascandy 2013-04-10 05:53:31

1
  • 使用new操作類需要創建依賴自己就足夠了!這意味着緊密耦合的代碼是您的答案。
  • 不遵循SOLID principles的代碼。

所以在測試中,您將無法使用Mock對象,因爲您正在自己創建依賴關係並對關係進行硬編碼。

With dependency injection您可以使用多態行爲,因此調用構造函數或方法中傳遞給它的依賴關係的某個方法的類不需要知道具體類型。所以在測試中你可以傳遞一個模擬對象,你將能夠輕鬆地測試你的類。

Misko's Writing testable code解釋我們如何擅長寫作的代碼是不可測試以及如何解決它。

實施例(JAVA):

//hard to unit test this code as testing class A also requires that ClassB should work properly 
//What is ClassB does some I/O or DB operations. This makes unit test a integration test 
class classA{ 
    ClassB b = new ClassB(); //Creating concrete dependencies 

} 

interface B{ 
    //implemented by Class B and your mock class that you create for testing 
} 

class ClassA{ 
    private B b; 

    //Here you can use mocking framework or create a mock class yourself and pass that as argument 
    //So the mock class will not do any DB or I/O and makes this unit test 
    public classA(B b){ 
     this.b = b; 
    } 
} 
2

好一些答案可能是

  • 它訪問數據庫
  • 根據系統日期時間
  • 一個代碼,其表現一個代碼的代碼其確實在同一梅索德多於一個的功能性(單位)
  • 一個代碼有很多coditio的最終行爲取決於另一個不可讀的代碼

並且在任何代碼中難以/不可能模擬環境以使其表現出需要測試的方式。

+0

訪問數據庫的代碼不再是單元測試。 – 2013-04-10 05:22:41

+0

@NarendraPathai代碼沒有單元測試,測試代碼的測試是單元測試,不應該測試訪問數據庫的單元,因此除了邏輯外還有一個訪問數據庫的邏輯組件,它是最不可能的,應該是不是單元測試 – CloudyMarble 2013-04-10 05:27:38

+0

我的意思是一個測試,試圖測試一個類訪問數據庫將不再是一個單元測試,應該被稱爲*集成測試*。 – 2013-04-10 05:30:03

1

這是一個很好的答案。緊密耦合的代碼對於單元測試是非常困難的(並且可能不應該進行單元測試 - 應該首先對其進行重新考慮),因爲根據定義,單元測試只能測試某個特定的單元。所有對數據庫或系統其他組件的調用都應該從單元測試中避免,因爲它們違反了這個規定。

雖這麼說,你也可以提,集成測試是很好用的依賴,甚至是基於行爲動作測試更大的代碼或代碼耦合。您可以構建一個集成測試套件,用於測試您的REST API,它具有許多依賴關係,甚至可以跨越許多技術和多種編程語言。

此外通過設計沒有考慮或不使用一個體面設計圖案可以導致極耦合或相關的代碼可以是困難的或不可能的單元測試,而無需重新因式分解或重新寫入。然後你可以談論TDD(測試驅動開發http://en.wikipedia.org/wiki/Test-driven_development)或BDD(行爲驅動開發http://en.wikipedia.org/wiki/Behavior-driven_development),這迫使你從設計測試套件開始並從那裏開始工作。

0

很難分開的代碼 - 多個職責之間分散了多個職責,但沒有任何職責完全承擔任何責任

代碼非常複雜 - 請嘗試500行的平均狀態機的if/then/else炸彈。

代碼在給定的領域非常強大,數學就是一個明顯的例子。採用傅里葉變換函數並添加一個單元測試,顯示全零變換爲全零。 100%的覆蓋率,但沒有真正的測試。

與外部相關性密切相關的代碼錯綜複雜地鏈接在一起。

代碼與巨大的接口,做多件事情。

相關問題