Java generics: How to wrap/extend Android Activity test case?
I am trying to extend ActivityInstrumentationTestCase2 as follows:
public abstract class FooActivityTestCase<T extends Activity>
extends ActivityInstrumentationTestCase2<Activity> {
public FooActivityTestCase(String pckg, Class<Activity> activityClass)
{
super(pckg, activityClass);
}
public void foo(){ ... }
}
I try to extend FooActivityTestCase
like this:
public class SpecificFooTestCase
extends FooActivityTestCase<MyActivity> {
public SpecificFooTestCase() {
super("foo.bar", MyActivity.class); // error on this line
}
}
Eclipse gives me the following error in the constructor:
The constructor FooActivityTestCase<MyActivity>(String, Class<MyActivity>) is undefined
I am pretty sure that the issue is with how I am using generics. When SpecificFooTestCase
extends ActivityInstrumentationTestCase2
I don't get any errors. Can anybody point out what I am doing wrong?
Kublai Khan's and Michael Myers' suggestions work in conjunction. 开发者_如何学运维After I changed FooActivityTestCase
to extend ActivityInstrumentationTestCase2<T>
and Class<Activity>
to Class<T>
in the constructor, the classes compile without errors. This is the resulting class (SpecificFooTestCase hasn't changed):
public abstract class FooActivityTestCase<T extends Activity>
extends ActivityInstrumentationTestCase2<T> {
public FooActivityTestCase(String pckg, Class<T> activityClass)
{
super(pckg, activityClass);
}
public void foo(){ ... }
}
You need to define the super constructor like this:
//Only accepts classes that are Activity or extend Activity
public FooActivityTestCase(String pckg, Class<? extends Activity> activityClass)
{
super(pckg, activityClass);
}
The thing is that for generics arguments, the generic type must always be exactly the same generic type, if you want to be able to pass something in the inheritance tree you need to use the wildcard ? and extends
, this way you can pass it any generic type that extends that class.
This is how I do Android unit testing:
public class MyInstrumentationTestRunner extends InstrumentationTestRunner
{
@Override
public TestSuite getAllTests()
{
InstrumentationTestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MyTestClass.class);
return suite;
}
@Override
public ClassLoader getLoader()
{
return MyInstrumentationTestRunner.class.getClassLoader();
}
}
And define your test classes as such:
public class myTestClass extends
ActivityInstrumentationTestCase2<Home>
{
Context _context;
public MyTestClass()
{
super("com.MyClassToTest", Home.class);
}
public void testfunction()
{
myFunction(_context);
}
@Override
protected void setUp() throws Exception
{
super.setUp();
setActivityInitialTouchMode(false);
Activity activity = getActivity();
_context = activity.getApplicationContext();
}
}
精彩评论