2

私はJavaでクラスを持っています。これには、デフォルト値を計算するためのプライベートメソッドがあります。そのうちの 1 つはその値を省略し、プライベート メソッドを使用してデフォルトを取得します。

public class C {
    private static HelperABC getDefaultABC() {
        return something; // this is a very complicated code
    }

    public C() {
        return C(getDefaultABC()); 
    }

    public C(HelperABC abc) {
        _abc = abc;
    }
}

今、私はこのクラスのテストを書き込もうとしており、両方のコンストラクターをテストしたいと考えています。2 番目のコンストラクターにはデフォルト値が渡されます。

さて、getDefaultABC()公開されていれば、それは些細なことです:

// We are inside class test_C
// Assume that test_obj_C() method correctly tests the object of class C
C obj1 = new C();
test_obj_C(obj1);

HelperABC abc = C.getDefaultABC();
C obj2 = new C(abc);
test_obj_C(obj2);

ただし、プライベートなのでgetDefaultABC()、テストクラスから呼び出すことはできません!!!.

だから、私は次のような愚かなことを書くことを余儀なくされています:

// Assume that test_obj_C() method correctly tests the object of class C
C obj1 = new C();
test_obj_C(obj1);

// here we will insert 20 lines of code
// that are fully copied and pasted from C.getDefaultABC()
//   - and if we ever change that method, the test breaks.
// In the end we end up with "HelperABC abc" variable
C obj2 = new C(abc);
test_obj_C(obj2);

メソッドをプライベートからパブリックに変更するだけでなく、この難問を解決する方法はありますか (理想的には、C.getDefaultABC()クラス test_C を除いて全員をプライベートとしてマークすることによって)。

4

4 に答える 4

4

Java にはフレンドに相当するものはありません。(上記のTIからのリンク) これを行う方法は、次のようにメソッドをパッケージ保護として宣言することです。

static HelperABC getDefaultABC()

getDefaultABC()これにより、テスト クラスが同じパッケージ内にある限り、テスト コードを呼び出すことができますC。もちろん、これにより同じパッケージ内の他のクラスでもそれを呼び出すことができますが、これと一緒に暮らす必要があると思います。リフレクションを使用せずにできる最善の方法です。ただし、リフレクションを使用すると、他のすべてのクラスもリフレクションを使用して呼び出すgetDefaultABC()ことができるため、ほとんど「脆弱」です。少なくともリフレクションを使用するよりも読みやすいように、パッケージを保護するだけです。


私はあなたに疑いの利益を与えるつもりであり、あなたはおそらくこのコードを継承しており、現在テストすることはできないと言います. あなたがする必要があるのはgetDefaultABC()、テスト可能な状態になるためにできることです。テストは必ずしも良いものである必要はありません。自信があれば十分です。テストにある程度自信が持てるようにgetDefaultABC()なると、デフォルトの ABC の取得とはまったく関係のないコードが に含まれていることがわかります。DB への接続などの低レベルの抽象化など。そのコードを特定し、独自のクラスに抽出する必要があります。次に、抽出されたクラスのより良いテストを作成します。

このコードを本当にクリーンな状態にリファクタリングすると、悪いテストを取り除き、元の状態にgetDefaultABC()戻すことができるはずprivateです。 private内部実装を意味します。内部実装を直接テストするべきではありません。

于 2013-06-26T19:56:15.623 に答える
2

完全にきれいというわけではありませんが、リフレクションを使用してテストでプライベート メソッドを呼び出すことができます。
非侵襲的であるため、リフレクションを使用する方が良いように思えます。テストのためだけにメソッドのアクセス修飾子を変更する必要はありません。

このようなもの:

    Method method = obj1.getClass().getMethod("getDefaultABC");
    method.setAccessible(true);
    HelperABC abc = (HelperABC) method.invoke(obj1);
于 2013-06-26T20:01:57.710 に答える
1

メソッドを保護する

protected static HelperABC getDefaultABC() {
        return something; // this is a very complicated code
    }

次に、テスト クラスを拡張します。

public class testC extends C{
   ...
}
于 2013-06-27T02:59:24.867 に答える
0

SUTとテストクラスが同じパッケージ(異なるソースフォルダー)にあるテストクラスに対して同じパッケージルールに従うことにより、パッケージレベルのアクセスを許可できる場合、よりクリーンなIMHOにすることができます。

于 2013-06-26T20:04:30.497 に答える