2009-07-08 110 views
61

我正在嘗試玩具項目中的測試驅動開發。我可以將測試工作用於我的類的公共接口(儘管我仍在編程,因爲我正在編寫比測試方法中更多的測試代碼)。Xcode中私有方法的單元測試

我傾向於使用很多私有方法,因爲我喜歡保持公共接口清潔;不過,我仍然想使用這些方法的測試。

由於可可是一種動態語言,我仍然可以調用這些私有方法,但我在我的測試中,我的類可能不會對這些方法的響應得到警告(雖然它顯然不會)。由於我喜歡編譯沒有警告,這裏是我的問題:

  1. 我如何關閉這些在Xcode中的警告?
  2. 還有什麼我可以做的關掉這些警告?
  3. 我在做'白盒'測試時做錯了什麼?
+0

到目前爲止,我還沒有在頭文件中公開我的私有方法。爲什麼我應該在頭文件中使用公共方法更優雅呢?但是,似乎我必須在objective-c中改變這一點。 – Nils 2012-01-10 13:01:38

+1

@Nils頭文件中沒有私有方法。一旦到達,它們就是公共方法。 – Abizern 2012-01-10 13:35:16

+0

是@Abizern到目前爲止,我遵循了下面的Peter Hosey的建議。 – Nils 2012-01-10 13:43:16

回答

88

我如何關閉在Xcode這些警告?

不要。

還有什麼我可以做的關掉這些警告?

不要。

我做得不對,試圖「白盒」測試?

解決的辦法是你的私有方法移動到它自己的頭一個類別。將此頭文件導入真實類和測試用例類實現文件。

+4

+1 - 偉大的建議!有關詳細信息,請參閱此問題/答案:http://stackoverflow.com/questions/1020070/#1020330例如,包含具有私有方法的類別的私有頭文件可以命名爲MyClass_Private.h。 – 2009-07-08 16:36:30

+2

感謝您的回答。我仍然不確定,但我必須承認,編寫測試然後通過測試是有趣的。 – Abizern 2009-07-09 10:58:17

4

看起來像另一個問題有了答案:Is there a way to suppress warnings in Xcode?

+1

這是答案的一部分,但對於某個特定案例來說最好的(或至少是更完整的)解決方案可能與Peter的答案或我的答案有關。 – 2009-07-08 17:15:05

+0

這也不是放置重複鏈接的地方。 – Rambatino 2014-10-08 17:37:39

124

請記住,在Objective-C中實際上沒有「私有方法」這樣的事情,而且這不僅僅是因爲它是一種動態語言。通過設計,Objective-C爲ivars提供了可見性修飾符,但不是用於方法的 - 您可以調用任何您喜歡的方法並非偶然。

@Peter的建議是一個偉大的。爲了補充他的答案,我使用的一個替代方案(當我不想/只需要一個頭部用於私人方法時)是在單元測試文件本身中聲明一個類別。 (我使用@interface MyClass (Test)作爲名稱)。這是一種添加方法的好方法,這些方法在發佈代碼中不必要的膨脹,比如訪問受測試類可以訪問的ivars。 (這顯然是不成問題的性質使用時)。

我發現這種方法可以很容易地揭露和證實的內部狀態,以及添加唯一的測試方法。例如,在this unit test file中,我寫了一個-isValid方法來驗證二進制堆的正確性。在生產中,這種方法會浪費空間,因爲我認爲堆是有效的 - 如果我修改代碼,在測試單元測試迴歸時我只關心它。

3

雖然擁有私人頭文件或定義自己的類別可能是更正確的解決方案還有另一個非常簡單的解決方案:在調用方法之前將對象強制轉換爲(id)。

3

如果您不想在多個源文件中分發您的私有方法實現,對Category解決方案的改進是在兩個導入的頭文件中定義一個擴展(實質上是一個匿名類別 - 參見Apple's documentation)你現有的類的實現和相關的單元測試源文件。

使用擴展允許編譯器在主@implementation塊中不存在私有方法的實現時發出警告。 This link很好地說明了這一點。

3

幾天前我開始使用TDD時,我正在處理同樣的問題。我發現這非常有趣的觀點在Test-Driven iOS Development書:

我經常被問,「我應該測試我的私有方法?」或相關的問題:「我應該如何測試我的私有方法?」的人問第二個問題假定第一個答案是「是」,現在正在尋找一種方法在他們的測試套件中公開他們的類的私有接口。

我的答案依賴於觀察一個微妙的事實:您已經測試了您的私有方法。通過遵循測試驅動開發中常見的紅綠重構方法,您設計了對象的公共API來完成這些對象需要執行的工作。通過測試指定的工作 - 並繼續執行測試,確保您沒有破壞任何東西 - 您可以自由組織班級的內部管道,只要您認爲合適。

您的私有方法已經過測試,因爲您所做的只是您已經進行過測試的重構行爲。在私有方法未經測試或未完全測試的情況下,您絕不應該因爲只有在您看到清理公共方法實現的機會時才創建它們。這確保了私有方法的存在只是爲了支持在測試期間必須調用的類,因爲它們肯定是從公共方法調用的。

0

簡單的工作。步驟: 1.你有 - (NSString *)getTestString;在接口的Foo目標米文件

  • 添加類別在單元測試文件:

    @interface DemoHomeViewController() - (的NSString *)getTestString; @end

  • 然後,做任何你想要的東西。