2014-01-20 146 views
4

我開始在我的項目中練習TDD,作爲背景它也包含遺留代碼。我們使用Mockito作爲模擬框架並遵循Spring MVC方法。單元測試和太多的模擬

有些時候有一個Service類實現與許多不同的DAO對象作爲@Autowired屬性。這些服務中有簡單的方法,例如completeTransaction

completeTransaction會使用很多DAO對象來完成其責任

  • 更新和保存交易
  • 推進業務流程
  • 關閉其他等待的操作

然而,執行這些操作時,該方法需要調用不同的DAO來獲取和更新t ransaction,獲取業務流程ID,獲取未決事務(並保存其更新)。這意味着單元測試這種方法使我添加了許多@Mock屬性。在測試完成之前,我需要設置模擬對象來測試某個條件。

這看起來像是一種代碼味道,對我來說,它幾乎感覺就像測試確保代碼的實現,而不僅僅是它的合約。再次,不嘲笑依賴關係,測試用例不會運行(由於NPE和其他)。

我可以按照如何清理代碼的策略是什麼? (儘管如此,我無法真正提供實際的源代碼)。我在想,有一種可能性是用類似於(「getPendingOperations」和「advanceBusinessProcess」)的方法來設置一個Facade類。然後我可以嘲笑一個依賴。但是,我認爲在所有其他有這種情況的課程中,我需要做同樣的事情,然後恐怕最終會出現許多「輔助」類,只是爲了進行更清潔的測試。

謝謝您的高級。

+0

我不認爲有任何開發人員沒有看到這一點,對於遺留代碼,我嘗試編寫測試來測試整個流程,以便模擬DAO並在Controller級別編寫測試,以允許服務和組件去做他們打算做的事...... –

回答

1

我認爲當你發現自己的嘲笑太多時,你會想做兩件事。這些並不是必須的,但您可能會發現它們很有幫助。

1)儘量讓你的方法和類更小。我認爲清潔代碼說有兩個規則,那就是班級應該很小。那個類應該比那個小。這是有道理的,因爲當你正在測試的單元(方法和類)變小時,依賴關係也會變小。你當然會得到更多的測試,但是他們在每個測試中的設置都會更少。

2)看看得墨忒耳定律(https://en.wikipedia.org/wiki/Law_of_Demeter)。有一些規則,但基本上,你想避免長長的字符串的屬性/方法調用。 objA = objB.propertyA.SomeMethod().propertyC;如果你需要模擬出所有這些對象來獲得objA,那麼你將會有很多設置。但是,如果你可以用objA = objB.newProperty;替換這個,那麼你只需要模擬objB並且它是一個屬性。

這些都不是銀子彈,但希望你可以在你的項目中使用這些想法。

+0

德米特法不是真的關於方法鏈接,而只關於屬性,請參閱http://www.yegor256.com/2016/07/18/law-of-demeter.html – yegor256

0

如果單元測試正在測試completeTransaction方法,那麼您必須嘲笑它​​所依賴的所有東西。由於您正在使用Mockito,因此您可以使用verify來確認調用了正確的模擬方法,並且它們按正確順序調用。

如果單元測試正在測試調用completeTransaction方法的東西,那麼只需模擬completeTransaction方法。

如果這是你的類層次結構:

 
    class A -> class B -> class C 

(其中 - >是 「依賴」)

在單元測試A類,模擬類只有B.

在單元測試類B,只模擬類C.

+0

是的,我明白需要嘲笑依賴關係,但是我想知道的是有時候依賴關係似乎失控了。當你的測試代碼最終創建了大量的'when().thenReturn()'來設置你正在測試的東西。當設置代碼變大時,很難保持測試。 –

+0

當「依賴關係失控」時,問題的根源不是單元測試,而是單元測試的類。如果您遇到大量設置的情況,請考慮使用非測試方法來初始化模擬對象。我建議不要使用非測試方法來確認單元測試的結果,但很樂意推薦他們進行設置。 – DwB

+0

我同意@DwB;一些私人的設置方法使其更容易。 –