[英]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
类放置在一个位置,使A
和ATest
属于同一包。
或者,在您的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(),
super.init()
。 我将其命名为callSuperInitForUnitTests()
类的名称,并在注释中明确指出这是单元测试的解决方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.