这是我的班级层次结构
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)
答案 0 :(得分: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);
希望它有所帮助。
答案 1 :(得分:1)
protected
类的成员不是visible来自另一个包的类,除非它是前者的子类。
但是,在您的应用程序中,类test.package.subpackage.ATest
正在尝试从package.subpackage
中的另一个类访问受保护的方法,这会导致访问冲突。
尝试将ATest
类放到某个位置,以便A
和ATest
属于同一个包。
答案 2 :(得分:1)
或者在TestClass中创建A的子类并通过公共方法公开受保护的方法:
public class TestClass extends TestCase(){
// ...
private class AChild extends A{
public exposeInit (String param1, String param2){
super.init(param1, param2);
}
}
}
现在你可以通过测试类AChild的初始化来测试A类的初始化。
我遇到了类似的问题,但是我们通过将设计改为组合而不是继承来解决它。
答案 3 :(得分:0)
也许我错过了一些东西,但是,因为B没有覆盖A.init()(至少从我能看到的)你可以去
B b = new B()
b.init(param1_specific_to_class_B, param2_specific_to_class_B)
如果B覆盖init(),
super.init()
添加一种特殊方法。我将其命名为callSuperInitForUnitTests()
,并在评论中明确指出这是单元测试的解决方法。