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

正确的做法是什么?


当前回答

在调试模式下构建时,你也可以将其声明为public或internal(使用InternalsVisibleToAttribute):

    /// <summary>
    /// This Method is private.
    /// </summary>
#if DEBUG
    public
#else
    private
#endif
    static string MyPrivateMethod()
    {
        return "false";
    }

它使代码膨胀,但在发布版本中它将是私有的。

其他回答

MbUnit有一个很好的包装,叫做Reflector。

Reflector dogReflector = new Reflector(new Dog());
dogReflector.Invoke("DreamAbout", DogDream.Food);

您还可以从属性中设置和获取值

dogReflector.GetProperty("Age");

关于“私人测试”,我同意…在完美的世界里。做私有单元测试是没有意义的。但在现实世界中,您可能最终希望编写私有测试,而不是重构代码。

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;
            }
        };

        ....    

    }
}

将它们声明为内部的,然后使用InternalsVisibleToAttribute允许单元测试程序集看到它们。

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

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

访问器

转到类定义的源代码 右键单击类名 选择“创建私有访问器” 选择要在其中创建访问器的项目 你将得到一个名为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[] {/* ... */} );

首先,您不应该测试代码的私有方法。你应该测试“公共接口”或API,即类的公共内容。API是所有公开给外部调用者的公共方法。

原因是一旦您开始测试类的私有方法和内部结构,您就将类的实现(私有的东西)耦合到您的测试中。这意味着当您决定更改实现细节时,您也必须更改您的测试。

出于这个原因,你应该避免使用internalsvisibletoattribute。

以下是Ian Cooper关于这个主题的演讲:Ian Cooper: TDD,哪里出了问题