4

How do I setup the unit test if the constructor is private (.NET)?

This is my class:

public class Class2
{
    // Private constructor.
    private Class2()
    {
    }

    public static Class2 getInstance()
    {

        if (x == null)
        {
            x= new Class2();
        }

        return x;
    }
}

This is my unit test:

[TestFixture]
public class Class2Tester
{
    private Class2 test;

    [SetUp()]
    public void SetUp()
    {
        // I cant do this. How should I setup this up?
        test = new Class2();
    }
}
4

6 回答 6

5

The answer is: you don't. Not because you can't, but because you shouldn't.

By making the constructor private, you're saying that its behavior is not part of the public API of the class. In this case its behavior either a) doesn't affect the public API of the class which means it doesn't need to be tested. b) more likely, does affect the public API of the class, in which case, write your tests around that public API, not the black-boxed constructor.

于 2009-02-23T03:51:26.917 回答
4

You don't specify a language so my answer will be generic. The typical way to do this is using reflection. You can do it directly in each test or by creating an accessor class that wraps all of the private methods/properties, including the constructor.

An example from C#/.NET

public void MyTest()
{
    MyClass class = typeof(MyClass).GetConstructor( null )
                                   .Invoke( null );
    ...
}

Or, more typically, after adding private accessors to your test project

public void MyTest()
{
    MyClass class = ((MyClass)new MyClass_Accessor()).Target;
}
于 2009-02-23T03:45:59.740 回答
3

在 java 中(假设唯一的构造函数是私有默认构造函数,否则需要检查数组):

Constructor[] constructors = YourClass.class.getDeclaredConstructors();
constructors[0].setAccessible(true);
YourClass currentInstance = (YourClass) constructors[0].newInstance(null);

然后,currentInstance 可供您使用。通常我只会为代码覆盖这样做,如果我将构造函数设为私有,通常是为了避免实例化。

于 2009-02-23T04:12:59.487 回答
2

取决于您在私有构造函数中所做的事情。如果您使用私有构造函数来禁止创建实用程序类的实例,那么我建议您抛出一个类似于您在 EJ2 中看到的非法访问错误。在这种情况下,您可以简单地通过不会被绕过的反射来测试它。

@Test(expected = InvocationTargetException.class)
public void privateConstructor() throws Exception {
    final Constructor<Keys> myConstructor = Keys.class.getDeclaredConstructor();
    myConstructor.setAccessible(true);
    myConstructor.newInstance();
}

我不反对这种类型的测试。它可以帮助找到意外创建 util 类的实例的地方,而你并不打算这样做(序列化/反序列化等)。

如果它们(强烈不推荐)是有状态的,也可能意味着一些令人讨厌的惊喜。

于 2010-11-30T18:22:50.023 回答
1

我通常根本不对构造函数进行单元测试。在这种情况下,您应该问自己的第一件事是您是否真的需要对该构造函数中的代码进行单元测试。当然,我们所有人中的偏执完美主义者有时会出来,所以如果答案是否定的,我说算了吧。

如果答案是肯定的,我认为你很有可能对你的构造函数和/或你的类做了太多的事情。即使不是这种情况,您也很有可能将确实需要进行单元测试的代码分解为它自己的公共函数。

诚然,总是有例外。但是我还没有遇到一个实例,我必须将构造函数设为私有并且必须对其进行单元测试。

于 2009-02-23T04:23:29.947 回答
0

Basically, you should not do that. See this question.

于 2009-02-23T03:47:11.687 回答