Android Junit

最近本来想尝试下 TDD的开发模式,所以就先写了Junit,然后再写code,没想到遇到很多问题,现总结下。


1. 由于一开始写的是跟SQLiteDatabase 打交道的Dao 层,所以感觉不需要用到 AndroidTestCase, 就用了TestCase

但是Run的时候老是出现问题,具体操作是: Run As --> Junit Test


出现的问题:

Invalid layout of java.lang.String at value
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (javaClasses.cpp:136), pid=2848, tid=1548
#  fatal error: Invalid layout of preloaded class
#
# JRE version:  (7.0_71-b14) (build )
# Java VM: Java HotSpot(TM) Client VM (24.71-b01 mixed mode windows-x86 )
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# E:\Eclipse2\adroid\Fellow\hs_err_pid2848.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#



2. 去网上查了下,解决上面的问题,可以使用这种方法:(当时还更新了下JDK呢,哎)

 配置claspath,移除掉Android library,重新跑一下: Run As -> Junit Test




Reference: http://blog.csdn.net/xinteng2012/article/details/19111311


3. 做到后面 ,发现有一个更为棘手的问题出现了: 当你想要在不同的Activity之间传递 对象时, 让该对象 implements Parcelable 是一个不错的选择

但是,如果这么做了的话,Junit 就过不了了,原因是:

    3.1.  Parcelable 是Android Platform的类: android.os.Parcelable 

    3.2. 但是第二步,我们又把Android library给remove掉了


出现的问题:

java.lang.NoClassDefFoundError: android/os/Parcelable
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
	at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
	at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	at com.fellow.dao.impl.FellowDaoImplTest.setUp(FellowDaoImplTest.java:18)
	at junit.framework.TestCase.runBare(TestCase.java:132)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
<span style="white-space:pre">	</span>Caused by: java.lang.ClassNotFoundException: android.os.Parcelable
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
	... 27 more


当时就想了一个捷径: 如果把Android library中的jar包 (android.jar, 在\platforms\android-19 下面)放到项目中的libs 目录下面是不是就可以解决问题了?

想到这,不禁看到一丝希望了,可是一跑Junit,发现这么一个错误:

java.lang.RuntimeException: Stub!
	at junit.framework.TestSuite.<init>(TestSuite.java:6)
	at org.junit.internal.runners.JUnit38ClassRunner.<init>(JUnit38ClassRunner.java:71)
	at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:14)
	at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
	at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
	at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
	at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:32)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:41)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:31)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


Google了一下,对上述描述,有这么一个解释:


android.jar contains only stub implementation of the classes. It provides the means for your app to build, once you have your APK you must run it on an android device or emulator.

If I'm not wrong you are trying to run on host's JVM.


Reference: http://stackoverflow.com/questions/8982631/error-java-lang-runtimeexception-stub-in-android-with-fitnesse-testing



4. 总结

 4.1.  在Android Project下,如果要跑Junit Case,如果该Case跟Android一点边都沾不到,比如某些 Helper类或者工具类,可以采用步骤二的方式进行: Run As --> Junit Test

 4.2.  如果跑的Case中要用到 Android的类,还是按部就班的啥都不要动,直接: Run As--> Android Junit Test 

所以,为了保险起见,还是Run As--> Android Junit Test  比较好点


如果说的不对或者不全的,欢迎高手前来补充




你可能感兴趣的:(android,JUnit)