我正在构建一个类库,它将有一些公共和私有方法。我希望能够对私有方法进行单元测试(主要是在开发过程中,但也可以用于将来的重构)。
正确的做法是什么?
我正在构建一个类库,它将有一些公共和私有方法。我希望能够对私有方法进行单元测试(主要是在开发过程中,但也可以用于将来的重构)。
正确的做法是什么?
当前回答
还请注意,internalsvisibletoattribute有一个要求,您的程序集必须是强命名的,如果您在一个以前没有这个要求的解决方案中工作,这就会产生它自己的一组问题。我使用访问器来测试私有方法。请看这个问题的例子。
其他回答
我倾向于不使用编译器指令,因为它们很快就会把事情弄得乱七八糟。如果你真的需要它们,一种缓解它的方法是把它们放在一个partial类中,并让你的构建在制作产品版本时忽略那个.cs文件。
JAVA语言
在这里,您可以使用模拟行为覆盖测试类的特定方法。
对于下面的代码:
public class ClassToTest
{
public void methodToTest()
{
Integer integerInstance = new Integer(0);
boolean returnValue= methodToMock(integerInstance);
if(returnValue)
{
System.out.println("methodToMock returned true");
}
else
{
System.out.println("methodToMock returned true");
}
System.out.println();
}
private boolean methodToMock(int value)
{
return true;
}
}
测试类将是:
public class ClassToTestTest{
@Test
public void testMethodToTest(){
new Mockup<ClassToTest>(){
@Mock
private boolean methodToMock(int value){
return true;
}
};
....
}
}
由于某些原因,私有类型、内部变量和私有成员是这样的,通常你不想直接打乱它们。如果您这样做了,很可能稍后会崩溃,因为不能保证创建这些程序集的人会保留私有/内部实现。
但是,有时,在对编译或第三方程序集进行一些hack /探索时,我自己最终想要初始化一个私有类或具有私有或内部构造函数的类。或者,有时,在处理无法更改的预编译遗留库时——我最终会针对私有方法编写一些测试。
因此诞生了AccessPrivateWrapper - http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html -它是一个快速的包装类,使用c# 4.0的动态特性和反射可以使工作变得容易。
您可以创建内部/私有类型,例如
//Note that the wrapper is dynamic
dynamic wrapper = AccessPrivateWrapper.FromType
(typeof(SomeKnownClass).Assembly,"ClassWithPrivateConstructor");
//Access the private members
wrapper.PrivateMethodInPrivateClass();
首先,您不应该测试代码的私有方法。你应该测试“公共接口”或API,即类的公共内容。API是所有公开给外部调用者的公共方法。
原因是一旦您开始测试类的私有方法和内部结构,您就将类的实现(私有的东西)耦合到您的测试中。这意味着当您决定更改实现细节时,您也必须更改您的测试。
出于这个原因,你应该避免使用internalsvisibletoattribute。
以下是Ian Cooper关于这个主题的演讲:Ian Cooper: TDD,哪里出了问题
我还使用了InternalsVisibleToAttribute方法。值得一提的是,如果你为了达到这个目的而将你之前的私有方法变成内部方法,那么也许它们不应该成为直接单元测试的对象。
毕竟,您是在测试类的行为,而不是它的具体实现——您可以在不更改前者的情况下更改后者,并且您的测试仍然应该通过。