执行Android JUnit测试时出现NoClassDefFoundError

时间:2012-09-22 16:17:52

标签: android eclipse junit noclassdeffounderror

首先,有类似问题,如herehere,但我既没有外部库也没有lib文件夹,也没有包含某些罐子或东西,所以我想知道我做错了什么通过运行Android Junit测试。

我的项目结构如下:
enter image description here

正如您所看到的,我有一个针对Android JUnit测试的单独项目。测试类看起来像这样:

public class PersistenceManager {
    private static final String FILENAME = "kpzwien_storage";

    public static void persist(String data, Context context) throws IOException  {
        FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
        fos.write(data.getBytes());
        fos.close();
    }

    public static String read(Context context) throws IOException  {
        FileInputStream fis = context.openFileInput(FILENAME);
        StringBuffer fileContent = new StringBuffer("");

        byte[] buffer = new byte[1024];
        while (fis.read(buffer) != -1) {
            fileContent.append(new String(buffer));
        }

        return fileContent.toString();
    }
}

这是测试用例:

public class PersistenceManagerTest extends AndroidTestCase {

    private final String FILENAME_PREFIX = "test.";

    @Before
    public void setUp() {
        MockContentResolver resolver = new MockContentResolver();
        RenamingDelegatingContext renamingDelegatingContext = new RenamingDelegatingContext(new MockContext(), getContext(), FILENAME_PREFIX);
        Context context = new IsolatedContext(resolver, renamingDelegatingContext);

        setContext(context);
    }

    public void testPersistAndRead() throws IOException {
        String testData = "foobar";

        PersistenceManager.persist(testData, getContext());

        String result = PersistenceManager.read(getContext());

        assertEquals(testData, result);
    }
}

测试项目的清单如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.devgems.android.kurzparkzonewien.androidtests"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="net.devgems.android.kurzparkzonewien.activities" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />
    </application>
</manifest>

targetPackage是Instrumentation对象将运行的应用程序,该应用程序由元素在其清单文件中分配的包名称标识。 (来源:http://developer.android.com/guide/topics/manifest/instrumentation-element.html

我的主项目中包的名称是

  

包= “net.devgems.android.kurzparkzonewien.activities”

所以它正是targetPackage指向的地方。如果我作为“Android JUnit测试”运行,我总是得到一个NoClassDefFoundError,但为什么?有任何想法吗?我正在使用 ADT 20.0.3 Eclipse Juno

最后这里是logcat输出:

  

09-22 16:00:12.745:I / TestRunner(1528):   java.lang.NoClassDefFoundError:   net.devgems.android.kurzparkzonewien.controller.PersistenceManager   09-22 16:00:12.745:I / TestRunner(1528):at   net.devgems.android.kurzparkzonewien.androidtests.PersistenceManagerTest.testPersistAndRead(PersistenceManagerTest.java:32)   09-22 16:00:12.745:I / TestRunner(1528):at   java.lang.reflect.Method.invokeNative(Native Method)09-22   16:00:12.745:I / TestRunner(1528):at   java.lang.reflect.Method.invoke(Method.java:521)09-22 16:00:12.745:   I / TestRunner(1528):at   junit.framework.TestCase.runTest(TestCase.java:154)09-22   16:00:12.745:I / TestRunner(1528):at   junit.framework.TestCase.runBare(TestCase.java:127)09-22   16:00:12.745:I / TestRunner(1528):at   junit.framework.TestResult $ 1.protect(TestResult.java:106)09-22   16:00:12.745:I / TestRunner(1528):at   junit.framework.TestResult.runProtected(TestResult.java:124)09-22   16:00:12.745:I / TestRunner(1528):at   junit.framework.TestResult.run(TestResult.java:109)09-22   16:00:12.745:I / TestRunner(1528):at   junit.framework.TestCase.run(TestCase.java:118)09-22 16:00:12.745:   I / TestRunner(1528):at   android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)   09-22 16:00:12.745:I / TestRunner(1528):at   android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)   09-22 16:00:12.745:I / TestRunner(1528):at   android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:430)   09-22 16:00:12.745:I / TestRunner(1528):at   android.app.Instrumentation $ InstrumentationThread.run(Instrumentation.java:1447)   09-22 16:00:12.745:I / TestRunner(1528):-----结束异常-----

1 个答案:

答案 0 :(得分:2)

我找到了解决方案。但它实际上是某种解决方法,因为我无法想象我通常需要修改这样的东西(也许有人知道更好的解决方案?):

我的主项目是一个Maven项目,在这个项目中我必须设置输出文件夹从 / bin ... 到/ 目标/类目标/测试类目标/生成源。我已经这样做了,因为只要我没有运行 mvn install。,我的主项目JUnit测试就找不到最新的代码更改。如果输出文件夹是目标/...,我无需运行 mvn install 即可在我的测试中进行最新更改。
现在的问题是Android测试项目在存储在主项目的目标中时找不到编译的源。当我将主项目中的输出文件夹设置为bin并运行 mvn install 时,Android测试项目现在可以找到这些类。我必须这样做一次。当我将其设置回目标时,我的Android测试仍然运行并且我的主要JUnit测试运行。当我更改主项目中的方法时,测试项目立即识别出更改,这意味着它不使用二进制jar或其他东西(这确实非常好,虽然我不明白它为什么现在找到它,虽然我把它设定回目标?)。

<强> [UPDATE]
将这两行添加到主项目的pom to build部分可以解决问题,因此我不再需要解决方法了。

    <outputDirectory>bin/classes</outputDirectory>
    <testOutputDirectory>bin/test-classes</testOutputDirectory>