或者最好使用另一種設計模式?如何用DUnit測試Singleton類?
回答
幾天前回復了類似的問題here, mocking a Singleton。原文是針對C#.Net關於嘲笑單身人士的行爲,但仍應適用。
至於單身模式,它本身沒有任何問題 - 在許多情況下我們想集中邏輯和數據。但是,單例和靜態類之間存在很大差異。將您的單例構建爲一個靜態類,硬編碼將其實現傳遞給應用程序中的每個消費者 - 這使單元測試變得非常困難!
你想要做的是爲你的單例定義一個接口,爲你的消費者提供使用方法。反過來,您的消費者通過傳遞對實現類的引用(通常這是您的應用程序,或者如果您熟悉依賴注入\控制反轉,則是容器)。
這是一個框架,無論是誰實例化的消費者,這是負責確保一個和唯一一個實例浮動。從靜態類到接口引用真的不是那麼大的一個飛躍[如上面的鏈接所示],你只是失去了一個全局訪問實例的便利 - 我知道我知道,全局引用非常誘人,但盧克轉身回到黑暗面,你也可以!
一般來說,最佳實踐建議避免靜態引用,並鼓勵對接口進行編程。請記住,仍然可以將這些約束應用於單例模式。按照這些指導原則,你應該沒有問題的單元測試你的工作:)
希望這會有所幫助!
單身!=公共靜態類,而單==單個實例
I'm using the following pattern當我寫,我可以模擬一個基於靜態的單身人士。代碼是Java,但我認爲你會得到一個想法。這種方法的主要問題是,你必須放鬆構造函數來保護包(這種類型擊敗了一個真正的單例)。 作爲一個方面說明 - 代碼適用於嘲笑你的「靜態」代碼而不一定只是調用它的代碼
缺乏可測試性是經典Singleton模型(返回實例的靜態類方法)的主要缺點之一。就我而言,這足以證明可以重新設計任何使用Singletons來使用其他設計的代碼。
如果你絕對需要一個單一的實例,那麼依賴注入和寫入接口,正如johnny g所建議的那樣,絕對是要走的路。
如果你必須使用一個單身人士(並有理由這樣做......但我會盡可能避免它)。我會建議使用IOC容器來管理它。我不知道是否有一個德爾福或不。但是在Java中你可以使用Spring,在.NET中你可以使用Windsor/Castle。一個IOC容器可以容納Singleton並且可以註冊不同的測試實現。
這可能是一個太大的主題進入這個片段以外的地方。
我通常只使用Flyton對象或類似值對象的單身。查看IoC容器(如上所述)可能是處理共享對象比單例更好的方法。
考慮到在Smalltalk(其中很多這些模式的起源),真假都是有效的單身:)
- 1. 如何測試Singleton類?
- 2. 如何測試PHP PDO Singleton類?
- 3. 如何使用DUnit測試私有方法?
- 4. DUNIT測試在MIDAS /的DataSnap項目
- 5. 如何從DUnit測試中獲得活動的TGUITestRunner?
- 6. 如何使Delphi DUnit測試在TSQLConnection.Connected = true時失敗
- 7. 使用Singleton進行單元測試
- 8. TIdHTTPServer在我的DUnit測試中激活EThread錯誤6時
- 9. Dunit控制檯模式 - 執行測試兩次
- 10. 如果類本身正在使用PowerMock進行測試,如何模擬Singleton類的私有方法?
- 11. Java:注入Singleton bean來測試
- 12. Singleton類
- 13. 如何從第一類(APEX類測試/ salesforce測試)中測試第二類func調用的http調用
- 14. 如何編寫測試類
- 15. 如何測試容器類?
- 16. 如何將我的測試類轉換爲JUnit測試用例?
- 17. 如何編寫用於OSGi(集成)測試的Arquillian測試類?
- 18. 如何測試在被測試的類中調用的方法?
- 19. 如何在laravel中使用phpunit測試特定測試類
- 20. DUnit:'Global'SetUp and TearDown
- 21. 如何製作一個jUnit4測試用例類Spring測試用例類?
- 22. 如何爲類中的所有測試設置測試類別
- 23. 如何測試使用DispatcherTimer的類?
- 24. 單元測試如何使用SmartGWT類?
- 25. ByteBuddy:如何使用java測試類。*
- 26. 如何使用Espresso測試抽象類?
- 27. 如何使用isinstance測試pywintypes.datetime類型?
- 28. 如何測試類和她的子類
- 29. 如何忽略測試類類與ArchUnit
- 30. 如何一次查看所有測試用例在DUnit GUI中的狀態消息?
...關於Smalltalk中:是的,但真假是_so_可測試:) – mjn 2011-12-01 13:51:49