1

失敗時にスローされる関数をテストする最良の方法は何ですか? または、障害の影響をかなり受けない機能をテストしますか?

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

これ(および私のコード内の同様の他の関数)が失敗した場合、コードは空白を含めて50行の長さであるため、私の質問は

a)それがスローされることをテストする価値は
ありますか b)テストする価値がある場合、どのように?
c) 単体テストが必要なため、単純なラッパー クラスを使用する必要がありますか?

CreateIoCompletionPortb) については、値をオーバーライドして渡すことを考えました。単体テストではそれをオーバーライドし、特定の値が渡されたときに 0 を返すようにします。ただし、これはコンストラクターで使用されるため、これは静的である必要があります。これは有効に見えますか?

4

4 に答える 4

3

これを .NET で実行している場合は、テストに追加できる ExpectedException 属性があります。

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

そのタイプの例外と指定されたメッセージがスローされた場合、テストは成功します。属性には、InnerExceptions などを含む他のオーバーロードがあります。

于 2008-08-11T09:30:32.643 に答える
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 の詳細は通常テストできます。例外的なケースが正常に機能することを知りたい場合は、おそらくテストする必要があります。

于 2008-08-11T08:57:26.097 に答える
1

I/O 完了ポートをモックできるような方法でコードを記述することを検討する必要があります。I/O オブジェクトで必要なメソッドを公開するインターフェイス/抽象クラスを作成し、想定どおりの処理を実行する実装を記述およびテストします (および、おそらく失敗をシミュレートするオプション)。

私の知る限り、依存関係を最小限に抑えるために、単体テスト時に外部リソースをモックするのは一般的な方法です。

于 2008-08-11T08:57:54.270 に答える
0

私にはC++のように聞こえます。Win32関数をモックアウトするには継ぎ目が必要です。CreateIoCompletionPort()たとえば、クラスでは、を呼び出す保護されたメソッドを::CreateIoCompletionPort()作成し、テストでは、I / O完了ポートクラスから派生し、オーバーライドCreateIoCompletionPort()して.を返すだけのクラスを作成しますNULL。本番クラスはまだ設計どおりに動作していますが、CreateIoCompletionPort()関数の障害をシミュレートできるようになりました。

この手法は、MichaelFeathersの著書「レガシーコードを効果的に使用する」からのものです。

于 2012-09-18T13:00:41.670 に答える