1

これが私のクラス階層です

abstract Class A
{
   int i = 0;
   protected init (String param1, String param2)
   {
       //do lots of common things based on param1, param2 and save data in i
   } 
}

次に、A ie を実装する 3 ~ 4 個のクラスがあります。

Class B extends A
{
    public B ()
    {
        super ();
    }

    public void performSomeAction ()
    {
        init (param1_specific_to_class_B, param2_specific_to_class_B); //calling parent class method 
        //do rest of teh random things
    }
}

今、私はクラス A の JUnit テストを書こうとしてinitいます。私はこれを試しました

Class clas = A.class;
B b = new B();

Method A_init;
A_init = clas.getDeclaredMethod("init", String.class, String.class);
A_init.invoke(b, param1_specific_to_class_B, param2_specific_to_class_B);

しかし、それは機能せず、次の例外が発生しています

java.lang.IllegalAccessException: Class test.package.subpackage.ATest can not access a member of class package.subpackage.A with modifiers "protected"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
    at java.lang.reflect.Method.invoke(Method.java:578)
    at test.package.subpackage.ATest.initTest(ATest.java:49)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
4

4 に答える 4

4

テストするクラスと同じパッケージにテスト クラスを配置できます。したがって、テスト クラスは保護されたメソッドにアクセスできます。

もう少し洗練された別のオプションは、保護されたメソッドにアクセスできるようにすることです。

A_init = clas.getDeclaredMethod("init", String.class, String.class);
A_init.setAccessible(true);
A_init.invoke(b, param1_specific_to_class_B, param2_specific_to_class_B);

それが役に立てば幸い。

于 2013-02-19T23:22:42.730 に答える
1

または、TestClass で A のサブクラスを作成し、パブリック メソッドを介して保護されたメソッドを公開します。

public class TestClass extends TestCase(){

   // ...

   private class AChild extends A{
      public exposeInit (String param1, String param2){
         super.init(param1, param2);
      }
   }
}

クラス AChild の init をテストすることで、クラス A の init をテストできるようになりました。

私も同様の問題を抱えていましたが、デザインを継承ではなく構成に変更することで解決しました。

于 2014-04-02T08:08:04.743 に答える
1

protectedクラスのメンバーは、別のパッケージのサブクラスでない限り、別のパッケージのクラスからは見えません。

ただし、アプリケーションで、クラスtest.package.subpackage.ATestが の別のクラスから保護されたメソッドにアクセスしようとするとpackage.subpackage、アクセス違反が発生します。

と が同じパッケージに属するATestような場所にクラスを配置してみてください。AATest

于 2013-02-19T23:12:28.680 に答える
0

たぶん私は何かが欠けているかもしれませんが、B は A.init() をオーバーライドしていないので (少なくとも、私が見ることができるものから)、あなたはただ行くことができます

B b = new B()
b.init(param1_specific_to_class_B, param2_specific_to_class_B)

B が init() をオーバーライドしている場合、

  1. すべてを同じパッケージに入れます(他の人が投稿したように)
  2. パッケージを変更できない、または変更したくない場合は、 を呼び出す特別なメソッドを B に追加する必要がある場合がありますsuper.init()。のような名前を付けてcallSuperInitForUnitTests()、これが単体テストの回避策であることをコメントで明確にします。
于 2013-02-19T23:23:17.490 に答える