2010-08-13 52 views
2

我有一個做一些IO通常看起來像這樣的方法:單元測試 - 不包括捕撈

public bool Foo() 
{ 
    try 
    { 
     // bar 

     return true; 
    } 
    catch (FileNotFoundException) 
    { 
     // recover and complete 
    } 
    catch (OtherRecoverableException) 
    { 
     // recover and complete 
    } 
    catch (NonRecoverableException ex) 
    { 
     ExceptionPolicy.HandleException(ex, "LogException"); 
     return false; 
    } 
} 

的方法不是關鍵任務的完成,也有外部的恢復步驟 - 並且拋出NonRecoverableException相對常見 - 規範中它返回false,報告'此時無法完成',並且處理也隨之移動。 NonRecoverableException不會使程序處於無效狀態。

當我的單元測試,而這些例外之一被拋出,我得到

Activation error occured while trying to get instance of type ExceptionPolicyImpl 

而且我想抑制有利於獲得實際/原始異常信息而不是錯誤EntLib無法記錄(並且實際上強制執行NonRecoverableException並且有一個[ExpectedException(typeof(NonRecoverableException))]單元測試,以確保此方法符合規範

我該如何解決這個問題?

編輯 使用預處理指令並不理想,因爲我討厭在代碼庫中看到特定於測試的代碼。

回答

10

使用Entlib靜態外觀的代碼的可測試性很難。在不改變你的代碼的情況下,你唯一的答案就是將一個app.config文件添加到你的測試程序集中,並用一個無用的策略來設置Entlib異常塊。

但是,在Entlib 4(和5中,我看到您正在使用)還有另一種方法。我們專門爲所有塊添加了一個實例入口點,以改進可測試性故事。對於異常塊,該實例是ExceptionManager。使用它非常簡單。獲取一個異常管理器實例到你的類型中,然後調用它而不是ExceptionPolicy。事情是這樣的:

public class Whatever { 
    private ExceptionManager exm; 

    public Whatever(ExceptionManager exm) { this.exm = exm; } 

    public bool Foo() { 
     try { 
      ... do whatever ... 
     } 
     catch(NonRecoverableException ex) { 
      exm.HandleException(ex, "LogException"); 
      return false; 
     } 
    } 
} 

現在你已經有了,在那裏,你可以模擬出ExceptionManager(它是一個抽象基類)基本測試期間無操作它,無論是手動或使用模擬對象框架。

如果您不想強制用戶使用DI容器,你可以添加一個默認的構造函數獲取當前異常管理:

public class Whatever { 
    private ExceptionManager exm; 

    public Whatever() : this(EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>()) { }   
    public Whatever(ExceptionManager exm) { this.exm = exm; } 
} 

最終用戶使用默認的構造函數,你的測試使用一個接受一個顯式的ExceptionManager,你有你的鉤子嘲笑任何Entlib使用。

所有塊現在都有這些「經理」類(無論如何它們都有意義)。

+0

那好吧;太棒了。非常感謝你。我打算將此標記爲已接受,但在一天左右時間內,希望您能得到更多讚揚以獲得如此好的答案。 – 2010-08-17 04:02:16

1

嗯,你可以重構代碼,將所有內容放在try塊中的一個單獨的方法中,並配置測試來調用它而不是現有的方法?

+0

我認爲這是一個好主意,但它是我正在創建的一個庫函數,我希望儘可能保持界面的清潔。 – 2010-08-14 22:38:11

+0

讓它變得私密還是內部? – Doobi 2010-08-14 22:45:47