2017-02-02 8 views
0

プライベート静的ジェネリックメソッドはどのようにテストされますか?内部は私のテストプロジェクトに見えます。どのようにしてこれらのメソッドをテストできますか?C#でのプライベート静的ジェネリックメソッドのテスト

internal class Foo { 

    // Non-static. This works! 
    private T TestThisMethod1<T>(T value) { 
     Console.WriteLine("Called TestThisMethod1"); 
     return value; 
    } 

    // Static. Can't get this to work! 
    private static T TestThisMethod2<T>(T value) { 
     Console.WriteLine("Called TestThisMethod2"); 
     return value; 
    } 

    // Static. Can't get this to work! 
    private static void TestThisMethod3<T>(T value) { 
     Console.WriteLine("Called TestThisMethod3"); 
    } 

    // Static. Can't get this to work! 
    private static void TestThisMethod4<T, T2>(T value, T2 value2) { 
     Console.WriteLine("Called TestThisMethod4"); 
    } 
} 

最初の例が有効です。静的ではありません。それはhttps://msdn.microsoft.com/en-us/library/bb546207.aspxの例です。対象は何度も議論されてきたこと:書面で

[TestMethod] 
public void PrivateStaticGenericMethodTest() { 

    int value = 40; 
    var foo = new Foo(); 

    // This works. It's not static though. 
    PrivateObject privateObject = new PrivateObject(foo); 
    int result1 = (int)privateObject.Invoke("TestThisMethod1", new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Fails 
    int result2 = (int)privateObject.Invoke("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic, new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Fails 
    PrivateType privateType = new PrivateType(typeof(Foo)); 
    int result2_1 = (int)privateType.InvokeStatic("TestThisMethod2", new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Fails 
    int result2_2 = (int)privateType.InvokeStatic("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic, new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) }); 

    // Stopping here. I can't even get TestThisMethod2 to work... 
} 

私の目的は、質問やプライベートメソッドをテストすることのメリットを議論するのはとてもではありません。さらに、質問を書く際の私の目的は、「PrivateObjectまたはPrivateTypeを使用してこれを行うことが可能なはずです。だから、どうすればいいのですか?

+2

プライベート静的メソッドのコンシューマーはありますか?いいえの場合は、なぜその動作をテストしますか? –

+7

一般的にプライベートメソッドは、 –

+0

と呼ばれるパブリックメソッドを使用してテストされます。本当に、私は通常、「パブリックメソッドのみをテストする」という規範に従います。今日は、私がそれを避けることができれば、何でも公開することはできません。このメソッドは非常に深いコードに埋め込まれています。このメソッドをPrivateObjectまたはPrivateTypeのいずれかと分離してテストすることができます。 – clarionprogrammer

答えて

5

あなたはプライベートメソッドをテストするつもりはありません。それらは変更可能な実装の詳細なので、パブリックインターフェイスをテストすることになっています。

パブリックインターフェイスをカバーした後にプライベートメソッドが適用されない場合は、パブリックインターフェイスを削除します。

+1

私はいつも「あなたはプライベートメソッドをテストするつもりはありません。 パブリックエントリポイントのみを持つ複雑なコンソールアプリケーションがあるとしたら、何もテストしませんか?メソッドのアクセシビリティを変更したいのは、テストしたいからです。 – clarionprogrammer

+0

コンソールアプリケーションが十分にモジュール化されておらず、パブリックエントリーポイントとして主なものしか持っていない場合は、単体テストを書く価値がないものを素早くハックするか、標準以下のソフトウェア設計です。コンソールアプリケーションはUIです...あなたのビジネス層とデータ層はプライベートメソッドであってはなりません。 – nvoigt

+0

コンソールアプリケーションは単なる例でした...私の意図は、プライベートメソッドをテストするかどうかを議論することではありません。 Microsoftは、プライベートメソッドをテストするためにPrivateObjectとPrivateTypeクラスを作成する価値がありました。私はそれらを正しく使用する方法を理解しようとしています。 – clarionprogrammer

2

最後に、ジェネリックタイプのテストを検索するGoogleでこれを行う方法が見つかりました。オブジェクトの自己要求を使用して、メソッドはmake genericメソッド呼び出しを実行し、最後に呼び出します。

[TestMethod] 
public void TestMethod2() 
{ 
    int value = 40; 
    var foo = new Foo(); 

    MethodInfo fooMethod = foo.GetType().GetMethod("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance); 
    if (fooMethod == null) 
    { 
     Assert.Fail("Could not find method"); 
    } 
    MethodInfo genericFooMethod = fooMethod.MakeGenericMethod(typeof(int)); 
    int result1 = (int)genericFooMethod.Invoke(typeof(int), new object[] { value }); 

    Assert.AreEqual(result1, value); 
} 
+0

これは解決策であり、質問に答えます。 私は、PrivateObjectやPrivateTypeが自分自身でリフレクションを実行することなく、これをバックグラウンドで行うことができると考えていました。残念なことに、この特定のシナリオではどちらも動作しないようです。 – clarionprogrammer

関連する問題