2016-12-17 108 views
2

我對於VIPER體系結構中協議的好處有點困惑。 我知道DI(依賴注入)通過協議實現,有助於避免對象間的直接依賴 - 我同意。IOS VIPER:協議如何幫助單元測試?

但我從使用的角度看待真正的好處,一個例子可能是 - 特別是協議如何幫助在單元測試中獲益(測試Interactor部分)。

我們不能通過方法實現相同的回調使用塊嗎? 希望有人能幫助我從使用的角度去理解一些示例

乾杯

回答

3

使用回調,例如從交互者到演示者,可以使測試演示者變得更加困難。

當編寫關於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,其具有諸如changeNamechangeAddress的動作。演示者實施了ProfileUserActions,而視圖接受了ProfileUserActions作爲依賴項。當用戶點擊屏幕上的一個按鈕時,視圖會發送適當的消息到其對象userActions

當我想添加分析時,我能夠創建一個新的,獨立的ProfileAnalytics類,它也實現了ProfileUserActions。我在View和Presenter之間插入了分析對象,該應用程序允許應用程序捕獲分析,而無需修改View或Presenter。

+0

謝謝您的詳細回覆。我通過協議的目的清除了。我仍然對UNIT Testing感到困惑:)抱歉。可能是一個示例代碼可以給我一個更好的圖片 – MaK

+0

嘿!對不起: - 你什麼時候編寫單元測試?編寫代碼之前,例如TDD?或者在代碼寫入後? –

+0

其實,我需要爲現有的代碼庫編寫單元測試,這是由viper模型構建的 - 計劃使用BDD。我實際上發佈了一個關於TDD與BDD的問題:) http://stackoverflow.com/questions/41264111/tdd-vs-bdd-rest-service – MaK

0

通過使用協議很容易讓你換出在你的VIPER結構的實現。例如,您可能有一個與正在寫入文件系統的類一起工作的交互器。您不希望在單元測試中測試文件系統,相反,如果您將文件系統寫入操作置於協議後面,則可以使用內存中的實現替換文件系統寫入操作。

至於交互者本身的一個協議,我認爲它可以讓你的選擇更實際一點。如果爲測試構建交互器很容易,並且不會在測試中引起任何副作用,那麼可能不需要該協議。另一方面,如果你必須創建一些其他的依賴關係,那麼它可能會付出代價來讓交互器符合協議,這樣你就可以更容易地僞造你從交互器獲得的輸出。