Is there a way to use junit.extensions.TestSetup f

2019-04-29 05:17发布

问题:

The android sdk source includes source for junit.extensions, but the classes are not in android.jar even though junit.framework and junit.runner are in there. I tried creating my own junit.extensions package and using the source included in the android sdk source, but I get a ClassCastException (see below). Something in android.test.suitebuilder is trying to cast the return value from the suite() method to a TestCase, even though suite returns a Test interface.

I want to use TestSetup class from junit.extensions, as in the following example (see http://etutorials.org/Programming/Java+extreme+programming/Chapter+4.+JUnit/4.7+One-Time+Set+Up+and+Tear+Down/):

public SomeTestCase extends TestCase {

  public static Test suite() {
    TestSetup setup = new TestSetup(new TestSuite(SomeTestCase.class)) {
      @Override
      protected void setUp(  ) throws Exception {
          // do your one-time setup here!
      }

      @Override
      protected void tearDown(  ) throws Exception {
          // do your one-time tear down here!
      }
    };
    return setup;
  }

  public void someTestMethod() { }

}

However, I get the following error:

05-21 08:10:14.152: I/TestRunner(1316): java.lang.RuntimeException: Exception during suite construction
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:238)
05-21 08:10:14.152: I/TestRunner(1316):     at java.lang.reflect.Method.invokeNative(Native Method)
05-21 08:10:14.152: I/TestRunner(1316):     at java.lang.reflect.Method.invoke(Method.java:511)
05-21 08:10:14.152: I/TestRunner(1316):     at junit.framework.TestCase.runTest(TestCase.java:154)
05-21 08:10:14.152: I/TestRunner(1316):     at junit.framework.TestCase.runBare(TestCase.java:127)
05-21 08:10:14.152: I/TestRunner(1316):     at junit.framework.TestResult$1.protect(TestResult.java:106)
05-21 08:10:14.152: I/TestRunner(1316):     at junit.framework.TestResult.runProtected(TestResult.java:124)
05-21 08:10:14.152: I/TestRunner(1316):     at junit.framework.TestResult.run(TestResult.java:109)
05-21 08:10:14.152: I/TestRunner(1316):     at junit.framework.TestCase.run(TestCase.java:118)
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:545)
05-21 08:10:14.152: I/TestRunner(1316):     at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)
05-21 08:10:14.152: I/TestRunner(1316): Caused by: java.lang.ClassCastException: com.somebody.test.SomeTestCase$1 cannot be cast to junit.framework.TestCase
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.suitebuilder.TestSuiteBuilder.build(TestSuiteBuilder.java:188)
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.InstrumentationTestRunner.onCreate(InstrumentationTestRunner.java:379)
05-21 08:10:14.152: I/TestRunner(1316):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3920)
05-21 08:10:14.152: I/TestRunner(1316):     at android.app.ActivityThread.access$1300(ActivityThread.java:123)
05-21 08:10:14.152: I/TestRunner(1316):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
05-21 08:10:14.152: I/TestRunner(1316):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-21 08:10:14.152: I/TestRunner(1316):     at android.os.Looper.loop(Looper.java:137)
05-21 08:10:14.152: I/TestRunner(1316):     at android.app.ActivityThread.main(ActivityThread.java:4424)
05-21 08:10:14.152: I/TestRunner(1316):     at java.lang.reflect.Method.invokeNative(Native Method)
05-21 08:10:14.152: I/TestRunner(1316):     at java.lang.reflect.Method.invoke(Method.java:511)
05-21 08:10:14.152: I/TestRunner(1316):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-21 08:10:14.152: I/TestRunner(1316):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-21 08:10:14.152: I/TestRunner(1316):     at dalvik.system.NativeStart.main(Native Method)

The suite() method of a TestCase is supposed to return a Test, but it appears something in android os is trying to cast it to a TestCase.

As one attempt to resolve the problem, I tweaked the TestDecorator class so that it subclassed TestCase instead of Test, but it still gave the same ClassCastException, which really mystified me.

By the way, there seems to be some doubt about android.jar containing junit, so here is a partial listing of android.jar contents:

$ jar tf android.jar | more
META-INF/
META-INF/MANIFEST.MF
assets/
assets/images/
assets/images/android-logo-mask.png
assets/images/android-logo-shine.png
assets/sounds/
assets/sounds/bootanim1.raw
assets/sounds/bootanim0.raw
assets/webkit/
assets/webkit/android-weberror.png
assets/webkit/togglePlugin.png
assets/webkit/nullPlugin.png
assets/webkit/youtube.html
assets/webkit/missingImage.png
assets/webkit/youtube.png
assets/webkit/textAreaResizeCorner.png
assets/webkit/play.png
junit/
junit/framework/
junit/framework/TestSuite.class
junit/framework/ComparisonFailure.class
junit/framework/Assert.class
junit/framework/TestListener.class
junit/framework/TestResult.class
junit/framework/Test.class
junit/framework/TestFailure.class
junit/framework/Protectable.class
junit/framework/TestCase.class
junit/framework/AssertionFailedError.class
junit/runner/
junit/runner/TestSuiteLoader.class
junit/runner/Version.class
junit/runner/BaseTestRunner.class

You can also see it listed in the package contents on the android reference site at https://developer.android.com/reference/packages.html. If you continue to doubt, please browse your copy of android.jar.

Any helpful suggestions? Has anyone successfully used junit.extensions.TestSetup with android?

标签: android junit