2017-02-02 37 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

控制台应用只是一个例子....我的意图不是讨论测试私有方法的价值。 微软在创建PrivateObject和PrivateType类来测试私有方法时看到了价值。我正在寻求理解如何正确使用它们。 – clarionprogrammer

2

终于找到了一种方法来做到这一点与谷歌搜索与泛型类型的测试。使用该对象的自我请求方法,然后通过make泛型方法调用运行并最后调用它。

[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