我正在为我的Android代码编写一些POJO测试。
我想用JDK本地运行它们(不是在模拟器上使用Dalvik) - 速度,JUnit 4,Mockito,并且能够在没有设备的情况下运行无头 - 所以我在Eclipse中有一个单独的“Java”项目。
如果我正在测试的方法恰好引用了Android SDK中的任何内容,例如: android.util.Log
,测试失败 - 这是有道理的,因为 android.jar
不在类路径中。重现我有这个测试用例:
public class FooTests {
@Test
public void testFoo() {
android.util.Log.d("x", "y");
}
}
如果我加 android.jar
显式到测试项目的类路径,我得到例外
java.lang.RuntimeException: Stub!
at android.util.Log.d(Log.java:7)
at com.example.FooTests.testFoo(FooTests.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
有没有办法让代码工作而不会嘲笑Android SDK依赖的最后一点?也许是一个被嘲笑的人 android.jar
已经存在?
编辑:现在我最终包装了类似的类 android.util.Log
并将它们注入到实例中,用于经典的基于IOC的测试。斯科特的PowerMock建议是我需要它的下一步。
稍后编辑: Robolectric!
我知道没有嘲笑android.jar。我使用Powermock来模拟一切。你可以做的一件事就是帮助你进行繁重的模拟,就是让你的扩展的android类如活动,片段,广播器等变薄,并让它们委托给pojo类。你可以做出一个基于风险的决定,不要隔离单元测试android扩展类,而是集成单元通过android测试框架或其他像Robotium测试它们。
对于Android中的真正隔离单元测试,对于我来说,对java jvm进行单元测试,所有合作类都是最好的方法。
我知道没有嘲笑android.jar。我使用Powermock来模拟一切。你可以做的一件事就是帮助你进行繁重的模拟,就是让你的扩展的android类如活动,片段,广播器等变薄,并让它们委托给pojo类。你可以做出一个基于风险的决定,不要隔离单元测试android扩展类,而是集成单元通过android测试框架或其他像Robotium测试它们。
对于Android中的真正隔离单元测试,对于我来说,对java jvm进行单元测试,所有合作类都是最好的方法。
我有同样的问题。我想在本地测试简单的POJO。
具体来说,我的代码想要使用android.util.Base64。
我最终做的是使用SDK安装Android 4源,并将android.util.Base64类复制到我的项目中。
令人惊讶的是,这很有效。
我有同样的问题。我想在本地测试简单的业务逻辑。
具体来说,我的代码使用 android.util.SparseArray<E>
。
我尝试了3种不同的方法,可以使用junit在android之外进行测试。
- 在我的业务逻辑中,我创建了一个接口并将其附加到
MySparseArray<E>
继承自 SparseArray<E>
。在junit-test中,我重新使用了接口 HashMap<Integer, E>
。这是有效的,但从长远来看,这需要做很多工作才能使业务逻辑单元可测试 android.*
是必要的。
- 正如@Tal Weiss所建议的,我添加了所需类的android java源代码:
android.util.SparseArray.java
用的 com.android.internal.util.ArrayUtils.java
。这也有效,但我不想添加更多的android源代码,特别是如果有更多的依赖项
- 我下载了一个存根二进制文件
android.jar
从旧的Android 2.2 http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1 并将其作为lib包含在我的junit-java-project中。此jar仅包含名称空间的类 android.*
, com.android.*
, dalvik.*
和 framework.base.*
。这也有效。
目前我成功避免使用 android.*
除了 SparseArray<E>
在我的业务层中,并且不依赖于Context,Activity或Service。我本来可以用的 HashMap<Integer, E>
在android-business层而不是 SparseArray<E>
。
unmock-plugin可以提供帮助 https://github.com/bjoernQ/unmock-plugin。就我而言,它适用于SparseArray。