单元测试SherlockFragmentActivity类导致无法找到从方法Y引用的类X.

时间:2014-04-06 12:51:49

标签: java android unit-testing actionbarsherlock

我尝试在我的应用程序中单独测试扩展SherlockFragmentActivity的活动,但没有成功。为了解决这个问题,我在一个非常简单的Sandbox项目中重现了它,但我无法弄清楚如何修复它。

我的配置

我使用最新版本的Eclipse和SDK& Linux Debian上的ADT 22.6.2。

该项目通过仿真器在Android 2.2仿真设备(API 8)中进行测试。

目标API是Android 4.4.2(API 19)。

JDK 1.6(我也尝试过使用JDK 1.7,参见Could not find class X referenced from method Y)。

问题

我无法在扩展SherlockFragmentActivity的类上运行单元测试。

这是Eclipse中Console选项卡的输出:

[2014-04-06 13:01:02 - SandboxTest] Dx 
trouble writing output: already prepared 
[2014-04-06 13:01:03 - SandboxTest] ------------------------------
[2014-04-06 13:01:03 - SandboxTest] Android Launch! 
[2014-04-06 13:01:03 - SandboxTest] adb is running normally.
[2014-04-06 13:01:03 - SandboxTest] Performing android.test.InstrumentationTestRunner JUnit launch 
[2014-04-06 13:01:03 - SandboxTest] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD 'Android_2.2' 
[2014-04-06 13:01:03 - SandboxTest] Uploading SandboxTest.apk onto device 'emulator-5554' [2014-04-06 13:01:03 - SandboxTest] Installing SandboxTest.apk... 
[2014-04-06 13:01:10 - SandboxTest] Success! 
[2014-04-06 13:01:10 - SandboxTest] Project dependency found, installing: Sandbox 
[2014-04-06 13:01:11 - Sandbox] Application already deployed. No need to reinstall. 
[2014-04-06 13:01:11 - SandboxTest] Launching instrumentation android.test.InstrumentationTestRunner on emulator-5554 
[2014-04-06 13:01:15 - SandboxTest] Test run failed: Test run failed to complete. Expected 2 tests, received 0

测试运行失败:测试运行未能完成。预计2次测试,收到0 是由于另一个问题,从LogCat输出中获取,即:

Could not find class 'com.example.sandbox.MainActivity', referenced from method com.example.sandbox.test.MainActivityTest.<init>
Could not find class 'com.example.sandbox.MainActivity', referenced from method com.example.sandbox.test.MainActivityTest.setUp

完整输出在这里:

Class resolved by unexpected DEX: Lcom/example/sandbox/MainActivity;(0x45fa69a0):0x127410 ref [Lcom/actionbarsherlock/app/SherlockFragmentActivity;] Lcom/actionbarsherlock/app/SherlockFragmentActivity;(0x45fa69a0):0x12f910
(Lcom/example/sandbox/MainActivity; had used a different Lcom/actionbarsherlock/app/SherlockFragmentActivity; during pre-verification)
Unable to resolve superclass of Lcom/example/sandbox/MainActivity; (824)
Link of class 'Lcom/example/sandbox/MainActivity;' failed
Could not find class 'com.example.sandbox.MainActivity', referenced from method com.example.sandbox.test.MainActivityTest.<init>
VFY: unable to resolve const-class 1031 (Lcom/example/sandbox/MainActivity;) in Lcom/example/sandbox/test/MainActivityTest;
Class resolved by unexpected DEX: Lcom/example/sandbox/MainActivity;(0x45fa69a0):0x127410 ref [Lcom/actionbarsherlock/app/SherlockFragmentActivity;] Lcom/actionbarsherlock/app/SherlockFragmentActivity;(0x45fa69a0):0x12f910
(Lcom/example/sandbox/MainActivity; had used a different Lcom/actionbarsherlock/app/SherlockFragmentActivity; during pre-verification)
Unable to resolve superclass of Lcom/example/sandbox/MainActivity; (824)
Link of class 'Lcom/example/sandbox/MainActivity;' failed
Could not find class 'com.example.sandbox.MainActivity', referenced from method com.example.sandbox.test.MainActivityTest.setUp
VFY: unable to resolve const-class 1031 (Lcom/example/sandbox/MainActivity;) in Lcom/example/sandbox/test/MainActivityTest;
Class resolved by unexpected DEX: Lcom/example/sandbox/MainActivity;(0x45fa69a0):0x127410 ref [Lcom/actionbarsherlock/app/SherlockFragmentActivity;] Lcom/actionbarsherlock/app/SherlockFragmentActivity;(0x45fa69a0):0x12f910
(Lcom/example/sandbox/MainActivity; had used a different Lcom/actionbarsherlock/app/SherlockFragmentActivity; during pre-verification)
Unable to resolve superclass of Lcom/example/sandbox/MainActivity; (824)
Link of class 'Lcom/example/sandbox/MainActivity;' failed
Class resolved by unexpected DEX: Lcom/example/sandbox/MainActivity;(0x45fa69a0):0x127410 ref [Lcom/actionbarsherlock/app/SherlockFragmentActivity;] Lcom/actionbarsherlock/app/SherlockFragmentActivity;(0x45fa69a0):0x12f910
(Lcom/example/sandbox/MainActivity; had used a different Lcom/actionbarsherlock/app/SherlockFragmentActivity; during pre-verification)
Unable to resolve superclass of Lcom/example/sandbox/MainActivity; (824)
Link of class 'Lcom/example/sandbox/MainActivity;' failed
Class resolved by unexpected DEX: Lcom/example/sandbox/MainActivity;(0x45fa69a0):0x127410 ref [Lcom/actionbarsherlock/app/SherlockFragmentActivity;] Lcom/actionbarsherlock/app/SherlockFragmentActivity;(0x45fa69a0):0x12f910
(Lcom/example/sandbox/MainActivity; had used a different Lcom/actionbarsherlock/app/SherlockFragmentActivity; during pre-verification)
Unable to resolve superclass of Lcom/example/sandbox/MainActivity; (824)
Link of class 'Lcom/example/sandbox/MainActivity;' failed
VFY: unable to resolve virtual method 8919: Lcom/example/sandbox/MainActivity;.findViewById (I)Landroid/view/View;

我已经尝试了什么

我尝试过以下解决方案:

没有任何效果。

沙盒项目

首先,我向您展示沙箱项目​​及其相关的沙盒测试项目,它可以帮助您轻松重现问题。

沙箱项目非常简短易懂。只有一个&#34;去&#34; LinearLayout中的按钮。点击时没有动作,没什么复杂的。

MainActivity.java

package com.example.sandbox;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="go" />

</LinearLayout>

的AndroidManifest.xml

请注意, android:theme =&#34; @ style / Theme.Sherlock&#34; 但由于MainActivity扩展了Activity而不是任何Sherlock,因此尚未使用*活动课程。

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

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

    <application
        android:allowBackup="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock" >
        <activity
            android:name="com.example.sandbox.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

SandboxTest项目

沙箱测试也很容易理解,我只是检查按钮的文字是&#34;去&#34; (我们不关心测试结果)。

MainActivityTest.java

package com.example.sandbox.test;

import android.content.Intent;
import android.test.ActivityUnitTestCase;
import android.widget.Button;

import com.example.sandbox.MainActivity;
import com.example.sandbox.R;

public class MainActivityTest extends ActivityUnitTestCase<MainActivity> {
    private MainActivity mActivity;

    public MainActivityTest() {
        super(MainActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();

        startActivity(new Intent(getInstrumentation().getTargetContext(), MainActivity.class),
                null, null);

        mActivity = getActivity();
    }

    public void testButton() {

        assertNotNull(mActivity);

        Button b = (Button) mActivity.findViewById(R.id.button);

        assertTrue(b.getText().toString().equalsIgnoreCase("go"));
    }

    public void testDummy() {
        assertTrue(true);
    }

}

什么有效

使用这个Sandbox项目,在SandboxTest项目中运行测试时,它按预期工作。

让我们重现问题

要重现这个问题,它非常简单,只需使用SherlockFragmentActivity而不是Activity扩展Sandbox项目的MainActivity,如下所示:

MainActivity.java(第2版)

package com.example.sandbox;

import android.os.Bundle;

import com.actionbarsherlock.app.SherlockFragmentActivity;

public class MainActivity extends SherlockFragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

执行此操作时,我遇到了本主题开头时提到的问题。

我尝试使用导入actionBarSherlock库的方式,但没有任何效果。

Eclipse项目中的库配置

我已经检查了很多关于未找到的类的QA,他们都讨论了导出libs并将jar文件放在libs /子目录等中。我尝试了一切,没有任何工作。我认为这与actionbarsherlock库有关。

尽管如此,让我们看看我目前关于libs /子目录的配置:

Sandbox项目:我有一个带有android-support-v4.jar的libs /子目录 SandboxTest项目:没有libs /子目录。

让我们看看Eclipse中每个项目的配置:

(我无法添加图片,因为我没有10个声誉......: - /)

沙盒项目(右键单击&gt;属性):

机器人:

  • 项目构建目标:Android 4.4.2
  • 图书馆:actionbarsherlock

Java构建路径:

  • “项目”标签无效
  • Libraries选项卡包含Android 4.4.2(android.jar),Android Dependencies(actionbarsherlock.jar),Android私有库(android-support-v4.jar)
  • 订单和导出标签(按此顺序):[ - ] Sandbox / src,[ - ] Sandbox / gen,[] Android 4.4.2,[X] Android私有库,[X] Android依赖项。

SandboxTest项目(右键单击&gt;属性):

机器人:

  • 项目构建目标:Android 4.4.2
  • 图书馆:actionbarsherlock(&lt;&lt; 这是一个错误删除,为了工作,请参阅本文末尾的编辑部分

Java构建路径:

  • “项目”标签包含“沙盒项目”
  • Libraries选项卡包含Android 4.4.2(android.jar),Android Dependencies(actionbarsherlock.jar),Android私有库(android-support-v4.jar)
  • 订单和导出标签(按此顺序):[ - ] SandboxTest / src,[ - ] SandboxTest / gen,[] Sandbox,[] Android 4.4.2,[X] Android私有库,[X] Android依赖项

我希望有人有个主意。我在这个问题上已经失去了半天...

谢谢! 杰里米。

编辑:解决方案&amp;解决方法

我发现了一个主要错误:SandboxTest项目必须依赖于actionbarsherlock。

我还建议使用JDK 1.6

删除依赖项后,“无法找到”类错误消失。它被这一个取代:

java.lang.IllegalStateException: You must use Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar, or a derivative.
at com.actionbarsherlock.internal.ActionBarSherlockCompat.generateLayout(ActionBarSherlockCompat.java:976)
at com.actionbarsherlock.internal.ActionBarSherlockCompat.installDecor(ActionBarSherlockCompat.java:902)
at com.actionbarsherlock.internal.ActionBarSherlockCompat.setContentView(ActionBarSherlockCompat.java:836)
at com.actionbarsherlock.app.SherlockFragmentActivity.setContentView(SherlockFragmentActivity.java:261)
at com.example.sandbox.MainActivity.onCreate(MainActivity.java:13)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.test.ActivityUnitTestCase.startActivity(ActivityUnitTestCase.java:159)
at com.example.sandbox.test.MainActivityTest.testText(MainActivityTest.java:18)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:204)
at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:194)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:520)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1447)

当您未在应用中使用其中一个Sherlock主题时,ActionBarSherlock中的典型错误。我在Sandbox项目中使用Theme.Sherlock(在我的真实应用程序中),但在我的SandboxTest项目中没有。

错误消息似乎告诉我,我必须在SandboxTest项目中使用Theme.Sherlock主题。但是如果我想这样做,我必须将依赖关系添加回actionbarsherlock,这将再次导致我的第一个问题。

解决方法

我找到了一种在SandboxTest项目中使用ContextThemeWrapper正确运行测试的方法。感谢fidanov,请在此处查看原始邮件:https://github.com/JakeWharton/ActionBarSherlock/issues/454#issuecomment-10472928

MainActivityTest(内部解决方法)

新的setUp()方法是:

@Override
    public void setUp() throws Exception {
        super.setUp();

        ContextThemeWrapper context = new ContextThemeWrapper(getInstrumentation()
            .getTargetContext(), R.style.HerculeTheme);
        setActivityContext(context);

        startActivity(new Intent(context, MainActivity.class),
                null, null);

        mActivity = getActivity();
    }

现在,当我运行单元测试时,它不再困扰我使用Theme.Sherlock并且它可以工作。

谢谢, 杰里米。

0 个答案:

没有答案