有什么方法可以使用任何 Mocking Framework 在 Android 中模拟静态函数。Mockito 可以模拟类,但不足以模拟静态函数。
任何帮助将不胜感激。
提前致谢
模拟通过使用面向对象、继承等概念来工作......
基本上是通过覆盖看起来像真实对象的对象/实例中的某些方法和行为,因为它们是这些真实对象的子类。
换句话说,模拟部分来自于实例上的重写方法。
无法覆盖静态方法 (afaik)。
因此,模拟静态调用并不容易(如果可能的话)。
事实证明,我在上面的陈述中是错误的,这是不可能的。
我应该在这个网站上搜索重复的问题。有关在某些情况下声称可以为您执行此操作的框架的一些链接,请参见下文。由于它们使用字节码,我不确定它们能否在 Android (ymmv) 上正常工作。
(感谢 Rohit 强迫我重新评估我的信念)
请改用这个:https ://bintray.com/linkedin/maven/dexmaker-mockito-inline-extended
它帮助我成功地模拟了 Android Instrumented Tests 中的静态方法,但请注意,此功能需要在至少具有 Android P的设备上运行。
这是我所做的:
替换androidTestImplementation 'org.mockito:mockito-android:2.28.0'
为androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito-inline-extended:2.28.0'
然后像这样模拟静态方法:
static class StaticTrojan {
static String staticOpen() { return "horse"; }
}
@Test
public void testStubbingStaticMethod() {
MockitoSession session = mockitoSession().spyStatic(StaticTrojan.class).startMocking();
try {
when(StaticTrojan.staticOpen()).thenReturn("soldiers");
assertEquals("soldiers", StaticTrojan.staticOpen());
} finally {
session.finishMocking();
}
// Once the session is finished, all stubbings are reset
assertEquals("horse", StaticTrojan.staticOpen());
}
如果您使用Kotlin,那么要模拟静态函数,您可以连接mockk库项目:
androidTestImplementation "io.mockk:mockk-android:1.12.0"
然后,如果您的测试位于应用程序模块中,则需要将一个添加AndroidManifest.xml
到androidTest目录。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="you.application.package">
<application
android:debuggable="true"
android:extractNativeLibs="true" />
</manifest>
然后您可以使用以下代码模拟静态函数:
import io.mockk.every
import io.mockk.mockkStatic
import io.mockk.unmockkStatic
import org.junit.Assert.assertEquals
import org.junit.Test
class TestMockingStaticFunction {
object StaticTrojan {
@JvmStatic
fun staticOpen(): String {
return "horse"
}
}
@Test
fun testMockingStaticFunction() {
assertEquals("horse", StaticTrojan.staticOpen())
mockkStatic(StaticTrojan::staticOpen)
val mockScope = every { StaticTrojan.staticOpen() } returns "solders"
assertEquals("solders", StaticTrojan.staticOpen())
unmockkStatic(StaticTrojan::staticOpen)
assertEquals("horse", StaticTrojan.staticOpen())
}
}
库API允许您轻松地模拟Kotlin对象,在上面的示例中,该对象仅用于使用@JvmStatic
注释创建静态函数。
注意!这种方法使用从API级别 28 开始在Android P中可用的JVMTI 。您的应用程序可以使用较小的API编写,但您必须仅在Android P设备或更新的设备上运行测试。