3

NUnit を使用して C# でプライベート メソッドの単体テストを行っています。

たとえば、私のメソッド (パブリックの場合) はArgumentNullException. ArgumentNullExceptionメソッドが次のようなものをスローすると断言できます。Assert.Throws<ArgumentNullException>(() => method.Call());

ただし、リフレクションを使用してプライベート メソッドを呼び出しているため、次のようTargetInvocationExceptionにスローするメソッドに対して a をアサートします。ArgumentNullExceptionAssert.Throws<TargetInvocationException>(() => methodInfo.Invoke(obj, new object[] { params }));

ArgumentNullExceptionそのプライベート メソッドに対してa ではなく aをアサートしてTargetInvocationException、そのコードをスキャンし、デバッグして調べるのではなく、そのコードが何をするのかを知ることができるようにしたいと思います。

ではなく、実際の例外に対してどのようにアサートしTargetInvocationExceptionますか?

: この質問は、パブリック メソッドとプライベート メソッドの単体テストの背後にある理論に対処するものではありません。私のチームと私は、プライベート メソッドを単体テストすることを決定しました。それが単体テストの方法であるかどうかは、この質問には関係ありません。私たちの理論的根拠を理解するには、この質問に対する最も支持された回答を参照してください。

4

3 に答える 3

7

私の答えを見つけました:

var exception = Assert.Throws<TargetInvocationException>(() => methodInfo.Invoke(obj, new object[] { params }));
Assert.IsInstanceOf<Exception>(exception.InnerException);

アップデート

Assert.IsNotNull(exception.InnerException)内部例外が存在することを知らせてくれます。スローされたAssert.IsInstanceOf<Exception>(exception.InnerException);任意のタイプをアサートします。Exceptionどちらの方法も、内部例外があることを示していることに同意します。

ただし.....特定のタイプの内部例外に対してアサートしたい場合はどうすればよいですか?

たとえば、メソッドが をスローした場合、Using をArgumentNullException実行しても内部例外が存在することを確認できますが、内部例外のタイプは明らかになりません。したがって、これが私がこの場合に使用することを好む理由です。Assert.IsInstanceOf<FileNotFoundException>(exception.InnerException);Assert.IsNotNullIsInstanceOf

于 2012-05-15T15:59:44.160 に答える
2

Assert で拡張メソッドを作成します。つまり、func を受け取り、Try/Catch でラップして InnerException をスローする "ThrowsInnerException" を作成します (この場合、ArgumentNullException に対応します)。

ここにコードがあります(エディターなしで入力したため、テストされておらず、コンパイルされませんが、アイデアが得られるはずです)

public static class AssertExtension 
    {
        public static void ThrowsInnerException<T>(Action action) 
        {
            Assert.Throws<T>(delegate() {
                try { action(); }
                catch (Exception exc) { throw exc.InnerException; }
            });
        }
    }
于 2012-05-15T15:31:12.970 に答える
0

プライベート メソッドの単体テストは良い考えですか? そうではないように聞こえるからです。

プライベート メソッドを呼び出しているパブリック メソッドをテストすることをお勧めします。

アップデート

さらに、あなたのコードは見ていませんが、パラメーターの検証をパブリック メソッドに配置してテストする方がよいと思います。

Update2
かなり似たSOの質問が見つかりました


同様のケースで(フィールドをモックするために)使用していたUpdate3アプローチは、メソッドprivateをマークし、テスト対象のアセンブリに属性を追加するだけでした。 それは良い考えではありません (実際、デザイン セッションの 1 つでチームで提案されたとき、それは正しくない、純粋ではないなどの理由で、私はこれに反対しました) が、結果として、単体テストを作成するための多くの時間を節約できました。privateinternalInternalsVisibleTo(<assembly_with_unit_tests>)

于 2012-05-15T15:19:35.550 に答える