2008-08-11 69 views
1

測試引發故障的函數的最佳方法是什麼?或者測試一個對失敗相當免疫的函數?測試引發故障的函數

例如;如果無法正確初始化端口,我有一個在構造函數中拋出的I/O完成端口類。這在初始化列表中使用CreateIoCompletionPort的Win32函數。如果句柄設置不正確 - 非空值 - 則構造函數將拋出異常。我從來沒有見過這個功能失敗。

我敢肯定,這(和其他功能,如它在我的代碼),如果他們無法將正確的行爲,代碼是50行,包括空格,所以我的問題是

a)是它值得測試,它會拋出
B),如果它值得測試,如何?
c)應該簡單的包裝類,因爲這些是單元測試?

對於b)我想過重寫CreateIoCompletionPort並傳遞值。在單元測試中覆蓋它,並在傳入某個值時使其返回0.但是,由於在構造函數中使用了它,因此這需要是靜態的。這看起來有效嗎?

回答

2

測試失敗條件是絕對值得的,無論您的類是否在您希望的時候正確地引發異常並且在類中正確處理了異常。

如果您在傳入構造函數的對象上進行操作,只需傳入一個模擬內容即可輕鬆完成此操作。如果不是,我傾向於將功能轉移到受保護的方法,並覆蓋受保護的方法來喚起我的失敗情況。我將使用Java作爲一個例子,但它應該是很容易移植的想法,一個C#案例:

public class MyClass { 
    public MyClass() throws MyClassException { 
     // Whatever, including a call to invokeCreateIoCompletionPort 
    } 

    protected int invokeCreateIoCompletionPort(String str, int i) { 
     return StaticClass.createIoCompletionPort(str, i); 
    } 
} 

public class MyTest { 
    public void myTest() { 
     try { 
      new MyClass(); 
      fail("MyClassException was not thrown!"); 
     } catch (MyClassException e) { 
     } 
    } 

    private static class MyClassWrapper extends MyClass { 
     @Override 
     protected int invokeCreateIoCompletionPort(String str, int i) { 
      throw new ExpectedException(); 
     } 
    } 
} 

正如你所看到的,這是很容易測試是否異常是由構造函數拋出的或者您正在測試的方法,並且從可以拋出異常的外部類中注入異常也很容易。對不起,我沒有使用你的實際方法,我只是用名字來說明它是如何聽起來像你正在使用它,以及我將如何測試它想要測試的情況。

基本上,您公開的任何API細節通常都可以進行測試,如果您想知道特殊情況下應該如何工作,那麼您可能需要測試它。

1

您應該考慮編寫代碼,以便您可以模擬您的I/O完成端口。創建一個接口/抽象類,它公開您在I/O對象上需要的方法,編寫和測試實現,執行它應該做的事情(也可以選擇模擬失敗)。

AFAIK通常的做法是在單元測試時嘲笑外部資源,以最小化依賴性。

3

如果您在.NET中這樣做,有一個的ExpectedException屬性,您可以添加到您的測試:如果該類型指定的消息,並與異常被拋出

[Test, ExpectedException(typeof(SpecificException), "Exception's specific message")] 
public void TestWhichHasException() 
{ 
    CallMethodThatThrowsSpecificException(); 
} 

測試將通過。該屬性有其他重載,包括有InnerExceptions等。

0

聽起來像C++給我。你需要一個接縫來模擬Win32函數。例如。在你的班級中,你將創建一個受保護的方法CreateIoCompletionPort(),它調用::CreateIoCompletionPort()並且爲了測試你創建了一個從你的I/O Completion Port類派生出來的類,並且重寫CreateIoCompletionPort()什麼都不做,只能返回NULL。您的生產班級仍像其設計的那樣工作,但您現在可以模擬CreateIoCompletionPort()功能中的故障。

該技術來自Michael Feathers的書籍「使用遺留代碼有效地工作」。