2015-04-17 79 views
7

blog article說:爲什麼用嘲笑DI比嘲笑objective-c中的對象更好?

雖然存在有時明智的方式來模擬出的對象,而不DI (通常通過嘲笑出類方法,如在上面的OCMock例子 看到),它往往平出不可能。即使有可能,測試設置的複雜性可能會超過其好處。如果 您一直在使用依賴注入,那麼您會發現編寫 使用存根和模擬測試會更容易。

但它不能解釋爲什麼。什麼是可能的情況,其中DI(注入id對象符合協議)將用於對在Objective-C嘲笑更好,比簡單OCMockito:

[given([mockArray objectAtIndex:0]) willReturn:@"first"]; 
[verifyCount(mockArray, times(1)) objectAtIndex:]; 

回答

1

我注意到,當原始類做一些異步的東西時,爲測試目標創建一個單獨的類更容易。

假設您爲UIViewController編寫了測試,該測試具有使用AFNetworking向API請求的LoginSystem依賴關係。 LoginSystem以塊參數作爲回調。 (UIViewController-> LoginSystem-> AFNetworking)。

如果您對LoginSystem進行了模擬,您可能會遇到問題,如何在成功/失敗時觸發回調模塊來測試您的UIViewController行爲。當我試圖以MKTArgumentCaptor結尾來檢索塊參數時,我不得不在測試文件中調用它。另一方面,如果您爲LoginSystem創建了一個單獨的類(讓我們稱之爲從LoginSystem擴展的LoginSystemStub),那麼您可以在3行代碼中和測試文件之外「模擬」行爲。我們也應該保持我們的測試文件乾淨可讀。

另一種情況是,verify()無法檢查異步行爲。 (smth2)更容易打電話給 .equal(水木清華)

編輯:

指針到NSError(NSError **)也起不到很好的與驗證(),它是更好地創建一個存根:d

+0

謝謝:)所以我認爲它符合我的狀態「只有當你需要一些超級定製行爲才更好。」 –

0

想象一下,您正試圖測試與其子對象之一交互的對象的更復雜的行爲。爲了確保父對象正常運行,您必須模擬子對象的所有方法,甚至可能跟蹤其變化的狀態。

但是,如果你這樣做,你只是寫了一個全新的對象,混亂和複雜的方式。編寫一個全新的對象並告訴父母使用它會更簡單。

+0

是你暗示在所有引入混亂的情況下對每一個依賴使用DI,然後創建一個單獨的模擬類,比OCMockito存根更清晰/不那麼複雜?我不這麼認爲。 –

+0

在大多數情況下,跟蹤模擬的變化狀態似乎毫無意義。你需要從模擬中唯一需要的是返回一些數據並找出是否調用了某些方法。 –

0

使用DI,您可以在運行時注入模型,但不會在您的類中綁定,而只會在配置中綁定。
當你想嘲笑你只是創建一個模擬模型,並注入,而不是你的真實數據。除了模型之外,您還可以在一行中更改您的實現。

請參閱here瞭解其背後的想法或here。免責聲明:當然,你可以嘲笑模型以外的其他東西,但這可能是最常見的用例。

+0

是的,我知道如何使用注入模擬類來模擬。我只是想知道,如果使用真正的課程在博客中說得那麼優秀,如果是這樣,爲什麼? –

0

答案是:這不是更好。只有你需要一些超級定製行爲才更好。

最好的一點是,您不必爲每個注入的類創建一個接口/協議,並且您可以將DI注入到真正需要注入的模塊中,從而使您的代碼變得更加清晰和更多YAGNI。

它適用於任何動態語言或帶反射的語言。爲了單元測試而創造如此多的混亂讓我覺得不好。