2008-08-11 7 views
1

失敗時にスローする関数をテストする最適な方法は何ですか?または、障害にかなり耐性のある機能をテストしますか?失敗時にスローする関数のテスト

たとえば、ポートを正しく初期化できない場合、コンストラクターにスローするI/O完了ポートクラスがあります。これは、初期設定リストにCreateIoCompletionPortのWin32関数を使用します。ハンドルが正しく設定されていない場合(null以外の値)、コンストラクターは例外をスローします。私はこの機能が失敗するのを見たことがありません。

私は私の質問は、a)は、それが

であるので、彼らは正しく動作します失敗した場合は、この(私のコードでそれのように、その他の機能)は、コードが長い空白を含めて50行であることをかなり確信していますそれがスローされることをテストする価値がある
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ユニットテスト時に外部リソースを模擬して依存関係を最小限に抑えることが一般的です。指定されたメッセージ、そのタイプのとで例外がスローされた場合

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

テストに合格します:

3

あなたは.NETでこれをやっている場合は、あなたのテストに追加することができますExpectedException属性があります。属性にはInnerExceptionsなどを含む他のオーバーロードがあります。

0

C++のようなサウンドです。 Win32の機能を模擬するためにシームが必要です。例えば。あなたのクラスで保護されたメソッドCreateIoCompletionPort()を作成し、::CreateIoCompletionPort()を呼び出し、テストではI/O完了ポートクラスを派生させたクラスを作成し、CreateIoCompletionPort()をオーバーライドしてNULLを返します。あなたのプロダクションクラスは設計どおりに動作していますが、CreateIoCompletionPort()関数のエラーをシミュレートできるようになりました。

このテクニックは、Michael Feathersの本「従来のコードで効果的に作業する」のものです。

関連する問題