我對於VIPER體系結構中協議的好處有點困惑。 我知道DI(依賴注入)通過協議實現,有助於避免對象間的直接依賴 - 我同意。IOS VIPER:協議如何幫助單元測試?
但我從使用的角度看待真正的好處,一個例子可能是 - 特別是協議如何幫助在單元測試中獲益(測試Interactor部分)。
我們不能通過方法實現相同的回調使用塊嗎? 希望有人能幫助我從使用的角度去理解一些示例
乾杯
我對於VIPER體系結構中協議的好處有點困惑。 我知道DI(依賴注入)通過協議實現,有助於避免對象間的直接依賴 - 我同意。IOS VIPER:協議如何幫助單元測試?
但我從使用的角度看待真正的好處,一個例子可能是 - 特別是協議如何幫助在單元測試中獲益(測試Interactor部分)。
我們不能通過方法實現相同的回調使用塊嗎? 希望有人能幫助我從使用的角度去理解一些示例
乾杯
使用回調,例如從交互者到演示者,可以使測試演示者變得更加困難。
當編寫關於Presenter處理輸入(從Interactor發送)的測試時,測試將不得不調用Presenter上的某個方法,這會導致Presenter在Interactor上進行調用,這會導致Interactor發送數據發送給演示者。
通過讓Presenter實現由Interactor定義的協議,您的測試可以直接在Presenter上調用相應的輸入方法。就宣佈協議而言,我以模擬角色的風格而不是對象(http://www.jmock.org/oopsla2004.pdf)來實踐TDD。這些協議通過關注對象的作用(它的作用),幫助提供更好的抽象,而不是如何做。
協議本身對單元測試沒有多大價值。您的單元測試將提供測試雙打(http://martinfowler.com/bliki/TestDouble.html),用於測試系統的相關性。即使您將依賴項作爲具體類來公開,您仍然可以爲測試創建測試雙打。
在Objective-C中,您可以使用模擬庫(如OCMock(http://ocmock.org)或OCMockito(https://github.com/jonreid/OCMockito))來創建具體類的存根,間諜或模擬。
在Swift中,您可以通過繼承每個用作依賴關係的具體類來創建測試雙打。
簡而言之,協議不是用來簡化單元測試,而是用來描述抽象層次更高的應用程序。
下面是如何具有抽象議定書是事後有益的一個示例:
我創建了一個協議,以表示用戶可以在屏幕上執行的操作,例如ProfileUserActions
,其具有諸如changeName
和changeAddress
的動作。演示者實施了ProfileUserActions
,而視圖接受了ProfileUserActions
作爲依賴項。當用戶點擊屏幕上的一個按鈕時,視圖會發送適當的消息到其對象userActions
。
當我想添加分析時,我能夠創建一個新的,獨立的ProfileAnalytics
類,它也實現了ProfileUserActions
。我在View和Presenter之間插入了分析對象,該應用程序允許應用程序捕獲分析,而無需修改View或Presenter。
通過使用協議很容易讓你換出在你的VIPER結構的實現。例如,您可能有一個與正在寫入文件系統的類一起工作的交互器。您不希望在單元測試中測試文件系統,相反,如果您將文件系統寫入操作置於協議後面,則可以使用內存中的實現替換文件系統寫入操作。
至於交互者本身的一個協議,我認爲它可以讓你的選擇更實際一點。如果爲測試構建交互器很容易,並且不會在測試中引起任何副作用,那麼可能不需要該協議。另一方面,如果你必須創建一些其他的依賴關係,那麼它可能會付出代價來讓交互器符合協議,這樣你就可以更容易地僞造你從交互器獲得的輸出。
謝謝您的詳細回覆。我通過協議的目的清除了。我仍然對UNIT Testing感到困惑:)抱歉。可能是一個示例代碼可以給我一個更好的圖片 – MaK
嘿!對不起: - 你什麼時候編寫單元測試?編寫代碼之前,例如TDD?或者在代碼寫入後? –
其實,我需要爲現有的代碼庫編寫單元測試,這是由viper模型構建的 - 計劃使用BDD。我實際上發佈了一個關於TDD與BDD的問題:) http://stackoverflow.com/questions/41264111/tdd-vs-bdd-rest-service – MaK