Java Android-单元测试无法引用Android类

Java Android-单元测试无法引用Android类,java,android,eclipse,unit-testing,junit,Java,Android,Eclipse,Unit Testing,Junit,我正在构建一个android应用程序,我想用JUnit测试对其进行单元测试,而不是android JUnit测试(因为用模拟器运行android测试需要很长时间) 环境: 蚀 安卓项目 Android测试项目(目标包=Android项目包) JUnit4/Mockito 使用JUnit运行单元测试(故意不使用Android JUnit) 只要我测试自己编写的、不依赖于Android类的类,一切都会顺利进行。但是,当我想为包含例如Log.I()语句或引用TextView语句的类编写测试时,我会

我正在构建一个android应用程序,我想用JUnit测试对其进行单元测试,而不是android JUnit测试(因为用模拟器运行android测试需要很长时间)

环境:

  • 安卓项目
  • Android测试项目(目标包=Android项目包)
  • JUnit4/Mockito
  • 使用JUnit运行单元测试(故意不使用Android JUnit)
只要我测试自己编写的、不依赖于Android类的类,一切都会顺利进行。但是,当我想为包含例如
Log.I()
语句或引用
TextView
语句的类编写测试时,我会遇到以下错误:

java.lang.NoClassDefFoundError:android/text/TextWatcher位于 java.lang.ClassLoader.defineClass1(本机方法)

Android应用程序清单:

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

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

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.cleancode.lifesaver" />
测试等级:

import org.junit.Test;
import com.cleancode.lifesaver.utils.CapCharacterTextValidator;

public class CapCharactersTextValidatorTests {

    @Test
    public void validateCharacters() {
        new CapCharacterTextValidator(null);
    }
}
我尝试将android库添加到android应用程序和android测试应用程序的导出库中,或者两个应用程序中的一个,但仍然没有任何东西给我一个绿色测试。不管我怎么做,我总是遇到这个
NoClassDefFoundError

我阅读了大部分android文档,但他们似乎非常喜欢在模拟器上使用android JUnit的方法(对我来说太慢了)

以下问答帖子也不能进一步帮助我:


任何帮助都将不胜感激

Hmm,找到了另一种选择,这可能是“唯一的办法”,因为我将全部转向Android JUnit测试

如果我创建了一个测试项目(只是一个普通的Java项目,使用JUnit和Android作为库,而不是Android测试项目),那么我就可以运行单元测试,而不必在类路径中查找Android库

如果您迫切希望采用与我相同的方法,那么您可能还会遇到下一个问题,即您的代码中不能有Android日志语句,因为当您执行例如
Log.I(“tag”,“msg”)
时,Android框架将抛出
RuntimeException

由于我仍然喜欢日志记录,我将
Log
类包装如下:

import android.util.Log;

public class Logger {

    private static boolean AllowLogging = true;

    public void disableAndroidLogging() {
        AllowLogging = false;
    }

    public static int d(String label, String message) {
        if (AllowLogging) {
            return Log.d(label, message);
        }
        return 0;
    }
}
我在设置测试类时禁用了记录器。这样我就避开了Android框架的例外情况

如果有人有更好的解决办法,我非常愿意听取建议

非常感谢


bas

嗯,找到了一个替代方案,这可能是“唯一的办法”,因为我现在将全部转向Android JUnit测试

如果我创建了一个测试项目(只是一个普通的Java项目,使用JUnit和Android作为库,而不是Android测试项目),那么我就可以运行单元测试,而不必在类路径中查找Android库

如果您迫切希望采用与我相同的方法,那么您可能还会遇到下一个问题,即您的代码中不能有Android日志语句,因为当您执行例如
Log.I(“tag”,“msg”)
时,Android框架将抛出
RuntimeException

由于我仍然喜欢日志记录,我将
Log
类包装如下:

import android.util.Log;

public class Logger {

    private static boolean AllowLogging = true;

    public void disableAndroidLogging() {
        AllowLogging = false;
    }

    public static int d(String label, String message) {
        if (AllowLogging) {
            return Log.d(label, message);
        }
        return 0;
    }
}
我在设置测试类时禁用了记录器。这样我就避开了Android框架的例外情况

如果有人有更好的解决办法,我非常愿意听取建议

非常感谢


bas

要在单元测试中运行依赖于Android框架的任何东西,必须使用Android测试运行程序。没有别的办法。框架必须存在。

要在单元测试中运行依赖于Android框架的任何东西,必须使用Android测试运行程序。没有别的办法。框架必须存在。

使用。它为您模拟所有Android类。

使用。它会为您模拟所有的Android类。

这是否意味着我应该在模拟器上运行我的单元测试,速度非常慢?这是否意味着我应该在模拟器上运行我的单元测试,速度非常慢?您不应该在单元测试中禁用任何内容,因为这意味着您正在测试与正常运行时不同的代码。有一些框架已经被设计成可以做你想做的事情。看到我的答案了吗…@Dave唯一的区别是消息没有写入日志。如果android允许
Log
语句,而不是在实际平台上运行,那就太好了,相反,他们选择抛出一个异常。其次,Android JUnit测试框架绝对不适合TDD往返。测试开始运行前大约需要30秒-1分钟。我在这里的答案是有效的,允许我使用junit和mockito,并在毫秒内运行我的测试(他们应该这样做)。因此,如果这是Android所能提供的最好的解决方案,那么我将坚持这种方法。赞成>反对。谢谢!Robolectric不使用Android JUnit或模拟器。您几乎被迫使用Maven,这需要几秒钟的时间来构建和运行测试,但它并不像我看到的替代方案那么糟糕。你不应该在单元测试中禁用任何东西,因为这意味着你正在测试不同于正常运行的代码。有一些框架已经被设计成可以做你想做的事情。看到我的答案了吗…@Dave唯一的区别是消息没有写入日志。如果android允许
Log
语句,而不是在实际平台上运行,那就太好了,相反,他们选择抛出一个异常。其次,Android JUnit测试框架绝对不适合TDD往返。测试开始运行前大约需要30秒-1分钟。我在这里的答案是有效的,允许我使用junit和mockito,并在毫秒内运行我的测试(他们应该这样做)。因此,如果这是Android所能提供的最好的解决方案,那么我将坚持这种方法。赞成>反对。谢谢!Robolectric不使用Android JUnit或模拟器。你是艾尔