2016-05-12 43 views
1

Rhino Mocks與使用依賴注入和構造函數注入的設計模式緊密耦合,但我通常不遵循依賴注入範例,也不喜歡爲我的測試工具重新構建我的解決方案。使用虛擬受保護的工廠方法來模擬在類中創建的對象?

採取這樣的場景:

class MyClass{ 
    public void MyMethod(...){ 
     var x = new Something(...); 
     x.A(); 
     x.B(); 
     x.C(); 
    } 
} 

難道是比較典型的和可以接受的,而不是做到以下幾點,因爲這不是我一般會想注入依賴的情況下 - 它可以是所考慮的一部分MyClass'行爲/邏輯。

class MyClass{ 
    public void MyMethod(...){ 
     var x = NewSomething(...); 
     x.A(); 
     x.B(); 
     x.C(); 
    } 
    virtual protected Something NewSomething(...){ 
     return new Something(...); 
    } 
} 

現在我可以(我認爲)延長MyClass無論是在我的測試項目的具體類,或使用犀牛...對不對?這是否是正確的b)合理的,普通的做事方式?

另一種方法,我可以看到比其他DI可能是因爲我其實在我的項目,該項目產生的所有實例根據需要ClassFactory類;那麼我會找到一種方法在我的測試中模擬/存根。但是這對我來說似乎'很臭',儘管我知道這是一些人使用的模式。

+2

這是什麼東西?如果你在你的構造函數中接受某種SomethingFactory(例如,只是一個'Func '),它肯定會更靈活......基本上你的prod代碼現在仍然與'Something'緊密耦合......我會嘗試開始考慮這是一個依賴。 –

+0

@JonSkeet是的,這將消除這個問題,但我沒有在批發DI上出售。讓我們不要在這裏討論這個討論(!),但是感謝您指出了另一種方法,這當然是有效的。 –

+0

那麼這是一個奇怪的問題 - 那麼你的方法的「合理性」肯定與其他方法的合理性有關 - 但你不願意討論這些方法。如果你只是問「這個代碼是否工作」,那麼答案是「是」,但你可以自己嘗試過...... –

回答

1

試圖讓舊代碼的可測試性,當我有這個用了好幾次,但它真的很喜歡回來,後來咬你。

基本上,嘲笑/贗品/ testdoubles是你的敵人。你應該恨他們,並避免他們(編輯注:我不是說不使用它們,我只是說,只有當你有使用它們)。從範例來看,所有代碼都是不好的代碼,我們應該儘可能少地編寫代碼來完成任務。有大量的測試雙打覆蓋虛擬方法會使你的代碼非常僵化。即使您的生產代碼只在一個地方調用該方法,也會使更改方法簽名變得非常痛苦,因爲您的測試雙打也會中斷。這也使得後來清理垃圾並實際上注入依賴關係變得很痛苦(是的,我認爲注入的東西是Objectively Better(tm))。

什麼它歸結爲是基本上是:是的,這麼做可以使你的代碼的可測試性,但沒有任何的好處,你通常得到測試。你wn't得到更好的設計,你就會有剛性碼等

我不會真的指向任何的手指雖然,因爲我喜歡我說的都用這個有時只是爲了得到一個測試最多見,如果事情作品。它可以是一個「足夠好」的臨時解決方案,但我最終的答案是「如果你完全可以避免它(並且還有測試代碼),可能不會。」

0

你會用你建議的方法來犧牲單一責任模式(SRP),並且可以說讓你的代碼難以閱讀,理解和維護,在我們談論之前就有一種氣味存在試驗。

如果您打算運行測試,但同時不遵循SOLID principles,那麼您在哪裏節省時間,可讀性或靈活性? (我真的很想知道)。

什麼DI原則讓你做的是完全脫離你的依賴運行測試,這是你想要做什麼。

面向對象的固體原理有很多很好的理由,但我總是願意學習和錯誤,但我必須說,我可能已經被幾年的固體代碼矇蔽了,並且成千上萬的綠色單元測試確保我的項目。

+0

它很臭,但我會說重新構建我的整個代碼庫以適合測試工具是多臭多臭。我也不想讓我的課變得更加難以作爲回報,使它們更容易_test_,這似乎倒退了! –

+0

我聽到你的聲音。重新設計一個巨石永遠不會在一次單程操作中完成。但是,沒有任何東西可以阻止你垂直進行管道。記住SOLID原則是爲了讓代碼更易於閱讀和理解。您可能認爲讓這些類對其他類有依賴關係會更方便,但從長遠來看,它會在後面咬你。如果您的NewSomething類需要更改,那麼您將被迫在使用它的任何地方執行該更改。那時你不再有氣味,但是惡臭惡臭:) –

相關問題