繁体   English   中英

JUnit测试:调用父类受保护的方法

[英]JUnit Testing: invoking parent class protected method

这是我的班级层次结构

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

然后有3-4个实现A的类,即

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)

您可以将测试类与要测试的类放在同一包中。 因此,测试类将有权访问受保护的方法。

另一个选择稍微优雅一点是使受保护的方法可访问:

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

希望能帮助到你。

一个类的protected成员对另一个包中的类是不可见的 ,除非它是前一个的子类。

但是,在您的应用程序中,类test.package.subpackage.ATest试图从package.subpackage另一个类访问受保护的方法,这会导致访问冲突。

尝试将ATest类放置在一个位置,使AATest属于同一包。

或者,在您的TestClass中,创建A的子类,并通过公共方法公开受保护的方法:

public class TestClass extends TestCase(){

   // ...

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

现在您可以通过测试AChild类的初始化来测试A类的初始化。

我有类似的问题,但是我们通过将设计更改为合成而不是继承来解决了。

也许我缺少了一些东西,但是,由于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()类的名称,并在注释中明确指出这是单元测试的解决方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM