在 C# 中测试私有静态泛型方法

cla*_*mer 1 c# generics testing methods static

如何测试私有静态泛型方法?内部结构对我的测试项目可见。如何测试这些方法?

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个例子有效。它不是静态的。这是来自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...
}
Run Code Online (Sandbox Code Playgroud)

我写这篇文章的目的并不是真正质疑或辩论测试私有方法的优点:这个问题已经被反复辩论过。更重要的是,我写这个问题的目的是说“应该可以使用 PrivateObject 或 PrivateType 来做到这一点。那么,怎么做呢?”

nvo*_*igt 5

您不应该测试私有方法。因为它们是可以更改的实现细节。您应该测试您的公共接口。

如果您的私有方法在覆盖公共接口后未覆盖,请将其删除。

  • 我不会总是遵守“你不应该测试私有方法”这一硬性规定。假设您有一个复杂的控制台应用程序,只有一个公共入口点,您不会测试任何东西吗?我不想仅仅因为我想测试一个方法而改变它的可访问性。 (4认同)

Bri*_*arm 5

终于找到了一种方法来通过谷歌搜索使用泛型类型进行测试。使用对象自身请求该方法,然后通过 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);
}
Run Code Online (Sandbox Code Playgroud)