我正在构建一个类库,它将有一些公共和私有方法。我希望能够对私有方法进行单元测试(主要是在开发过程中,但也可以用于将来的重构)。

正确的做法是什么?


当前回答

测试私有方法可能没有用处。然而,我有时也喜欢从测试方法调用私有方法。大多数时候为了防止代码重复用于测试数据生成…

微软为此提供了两种机制:

访问器

转到类定义的源代码 右键单击类名 选择“创建私有访问器” 选择要在其中创建访问器的项目 你将得到一个名为foo_accessor的新类。 该类将在编译期间动态生成,并提供所有公共成员。

然而,当涉及到原始类的接口更改时,该机制有时有点棘手。所以,大多数时候我避免使用这个。

PrivateObject类 另一种方法是使用microsoft。visualstudio。testtools。unittest。privateobject

// Wrap an already existing instance
PrivateObject accessor = new PrivateObject( objectInstanceToBeWrapped );

// Retrieve a private field
MyReturnType accessiblePrivateField = (MyReturnType) accessor.GetField( "privateFieldName" );

// Call a private method
accessor.Invoke( "PrivateMethodName", new Object[] {/* ... */} );

其他回答

在极少数情况下,我想要测试私有函数,我通常会将它们修改为受保护的,并且我已经编写了一个带有公共包装器函数的子类。

类:

...

protected void APrivateFunction()
{
    ...
}

...

测试子类:

...

[Test]
public void TestAPrivateFunction()
{
    APrivateFunction();
    //or whatever testing code you want here
}

...

这里有一篇关于私有方法单元测试的好文章。但是我不知道哪个更好,是让你的应用程序专门为测试而设计(就像只为测试而创建测试)还是使用反射来测试。 我敢肯定大多数人都会选择第二种方式。

如果你正在使用。net,你应该使用InternalsVisibleToAttribute。

你可以用两种方法对私有方法进行单元测试

you can create instance of PrivateObject class the syntax is as follows PrivateObject obj= new PrivateObject(PrivateClass); //now with this obj you can call the private method of PrivateCalss. obj.PrivateMethod("Parameters"); You can use reflection. PrivateClass obj = new PrivateClass(); // Class containing private obj Type t = typeof(PrivateClass); var x = t.InvokeMember("PrivateFunc", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, obj, new object[] { 5 });

如果您想对私有方法进行单元测试,那么可能会出现一些错误。单元测试(一般来说)用于测试类的接口,即类的公共(和受保护)方法。你当然可以“破解”一个解决方案(即使只是通过公开方法),但你可能还想考虑:

如果您想测试的方法确实值得测试,那么将它移到自己的类中可能是值得的。 向调用私有方法的公共方法添加更多测试,测试私有方法的功能。(正如评论者所指出的,只有当这些私有方法的功能确实是公共接口的一部分时,才应该这样做。如果它们实际上执行对用户隐藏的功能(即单元测试),这可能是不好的)。