android sdkソースにはjunit.extensionsのソースが含まれていますが、junit.frameworkとjunit.runnerが存在していても、クラスはandroid.jarにありません。独自のjunit.extensionsパッケージを作成し、android sdkソースに含まれているソースを使用しようとしましたが、ClassCastExceptionが発生します(以下を参照)。suiteがTestインターフェースを返す場合でも、android.test.suitebuilderの何かがsuite()メソッドからの戻り値をTestCaseにキャストしようとしています。
次の例のように、junit.extensionsのTestSetupクラスを使用したい(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() { }
}
ただし、次のエラーが発生します。
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)
TestCaseのsuite()メソッドはテストを返すことになっていますが、AndroidOSの何かがそれをTestCaseにキャストしようとしているようです。
この問題を解決するための1つの試みとして、TestDecoratorクラスを微調整して、TestではなくTestCaseをサブクラス化しましたが、それでも同じClassCastExceptionが発生し、本当に不思議に思いました。
ちなみに、junitを含むandroid.jarには疑問があるようですので、android.jarの内容の一部を以下に示します。
$ 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
また、Androidリファレンスサイト(https://developer.android.com/reference/packages.html )のパッケージコンテンツにリストされていることも確認できます。引き続き疑問がある場合は、android.jarのコピーを参照してください。
役立つ提案はありますか?誰かがandroidでjunit.extensions.TestSetupを正常に使用しましたか?