2010-11-03 23 views
1

引入一個TestSettings類是爲了提供一個內部有很多進程的方法的靈活的測試可能性,這是一個好習慣嗎?將一個TestSettings參數注入到一個方法使其(單元或集成)可測試是否是一個好主意?

也許不是一個很好的例子,但也可以是簡單的:假設我有這樣的方法,我想測試它的子流程:

public void TheBigMethod(myMethodParameters parameter) 
{ 

    if(parameter.Condition1) 
    { 
    MethodForCondition1("BigMac"); 
    } 

    if(parameter.Condition2) 
    { 
    MethodForCondition2("MilkShake"); 
    } 

    if(parameter.Condition3) 
    { 
    MethodForCondition3("Coke"); 
    } 

    SomeCommonMethod1('A'); 
    SomeCommonMethod2('B'); 
    SomeCommonMethod3('C'); 
} 

想象着我對所有

    單元測試
  • 空隙MethodForCondition1(字符串s)
  • 空隙MethodForCondition2(字符串s)
  • 空隙MethodForCondition3(字符串s)
  • 空隙SomeCommonMethod1(炭C)
  • 空隙SomeCommonMethod2(炭C)
  • 空隙SomeCommonMethod3(炭C)

現在我想通過引入這樣的試驗方法,在需要斷言測試TheBigMethod本身其中:

  • TheBigMethod_MethodForCondition1_TestCaseX_DoesGood
  • TheBigMethod_MethodForCondition2_TestCaseY_DoesGood
  • TheBigMethod_MethodForCondition3_TestCaseZ_DoesGood
  • TheBigMethod_SomeCommonMethod1_TestCaseU_DoesGood
  • TheBigMethod_SomeCommonMethod2_TestCaseP_DoesGood
  • TheBigMethod_SomeCommonMethod3_TestCaseQ_DoesGood

所以,我想TheBigMethod是出口能夠在某些點上,如果它是由我的集成測試上面一個叫。

public void TheBigMethod(myMethodParameters parameter, TestSettings setting) 
{ 

    if(parameter.Condition1) 
    { 
    MethodForCondition1("BigMac"); 

    if(setting.ExitAfter_MethodForCondition1) 
     return; 

    } 

    if(parameter.Condition2) 
    { 
    MethodForCondition2("MilkShake"); 

    if(setting.ExitAfter_MethodForCondition2) 
     return; 

    } 

    if(parameter.Condition3) 
    { 
    MethodForCondition3("Coke"); 

    if(setting.ExitAfter_MethodForCondition3) 
     return; 

    } 

    SomeCommonMethod1('A'); 
    if(setting.ExitAfter_SomeCommonMethod1) 
     return; 

    SomeCommonMethod2('B'); 
    if(setting.ExitAfter_SomeCommonMethod2) 
     return; 

    SomeCommonMethod3('C'); 
    if(setting.ExitAfter_SomeCommonMethod3) 
     return; 
} 

即使它看起來它做什麼,我需要引入TestSetting參數可以makee代碼的可讀性變差,不看不錯的測試邏輯和主要功能合併到我。

你能否建議爲這種情況提供更好的設計,以便它可以替代TestSetting參數的想法?

謝謝

+0

在TDD中,您編寫測試以幫助並實現正確的設計(即先測試)。在你已經有了設計之後,你似乎正在寫測試 - 這是**不是** TDD。 – Oded 2010-11-03 10:06:23

+1

爲什麼你需要提前退出該方法? – 2010-11-03 10:09:55

+0

@Oded:正確。感謝您強調它。實際上,當我得到一個沒有測試的遺留代碼時,我想出了這個問題。無論如何,你對我的問題有意見或建議嗎?我將不勝感激。 – pencilCake 2010-11-03 10:10:32

回答

2

它會(IMO)是一個非常糟糕的事情添加此TestSetting。另一種方法是爲MethodForCondition X和SomeCommonMethod X添加一個接口(或一組接口)。測試每個MethodForCondition的 X &在隔離SomeCommonMethod X並傳遞用於TheBigMethod存根,其驗證了MethodForCondition X被調用值Z.

編輯:如果您不想使用接口,也可以使這些方法爲虛擬。

+0

所以,也許對於將要完成的所有流程,我可以介紹有所有進程的公共方法IBigMehtodManager接口(MethodForCondition * X *和SomeCommonMethod * X *),我可以在我的測試存根實現IBigMethodManager Basicaly我replacec帶有stub的BigMehtodManager類TestableBigMethodManager:IBigMethodManager。 – pencilCake 2010-11-03 10:27:00

+0

所以最後的方法簽名會是這樣---->公共無效TheBigMethod(myMethodParameters參數,IBigMethodManager經理) – pencilCake 2010-11-03 10:28:35

+0

我可能會注入「IBigMethodManager」進級,而不是僅僅是方法(除非TheBigMethod是靜態的) 。但這是總體思路。 – 2010-11-03 10:46:16

2

這裏有點晚了,但我會同意混合測試和生產代碼是一個大代碼的氣味要避免。遺留代碼中的大方法提供了各種問題。我強烈推薦閱讀Michael Feather的Working Effectively with Legacy Code。這就是處理遺留代碼中遇到的無數問題以及如何處理這些問題。

+0

感謝您指出本書。我已經添加到我的列表中。 – pencilCake 2010-11-04 08:27:41

相關問題