4

コンストラクターがプライベート (.NET) の場合、単体テストをセットアップするにはどうすればよいですか?

これは私のクラスです:

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

    public static Class2 getInstance()
    {

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

        return x;
    }
}

これは私の単体テストです:

[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

答えは次のとおりです。できないからではなく、すべきではないからです。

コンストラクターをプライベートにすることで、その動作がクラスのパブリック API の一部ではないことを意味します。この場合、その動作は a) クラスのパブリック API に影響しないため、テストする必要はありません。b) クラスのパブリック API に影響を与える可能性が高くなります。その場合、ブラックボックス化されたコンストラクターではなく、そのパブリック API を中心にテストを記述します。

于 2009-02-23T03:51:26.917 に答える
4

言語を指定しないので、私の答えは一般的なものになります。これを行う典型的な方法は、リフレクションを使用することです。各テストで直接行うか、コンストラクターを含むすべてのプライベート メソッド/プロパティをラップするアクセサー クラスを作成して行うことができます。

C#/.NET の例

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

または、より一般的には、プライベート アクセサーをテスト プロジェクトに追加した後

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 で見られるのと同様の illegalaccesserror をスローすることをお勧めします。その場合、バイパスされないことをリフレクションを介して簡単にテストできます。

@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

基本的にはやるべきではありません。この質問を参照してください。

于 2009-02-23T03:47:11.687 に答える