使用 Mockk 调用 JNI 的模拟方法
Mocking methods that call JNI with Mockk
我正在尝试向现有的 Android 应用程序添加单元测试,该应用程序具有一些 JNI 库(仅适用于 ARM)。我正在使用 Mockk
和 Junit4
,我有以下内容:
这个静态class是我的,它调用了外部SDK的initialize
方法(给我的,我没有权限访问他们的代码)。
internal class DeviceSDK {
companion object {
internal fun initialize() {
val success = ExternalSDK.getInstance().init() // it fails here 2
return success
}
}
}
init
方法为某些本机库调用 loadLibrary
。
在我的测试中 class,我有以下内容:
class MyDeviceTest {
private val sdkInstance = mockk<ExternalSDK>()
@Before
fun setUp() {
mockkStatic(ExternalSDK::class) {
every { ExternalSDK.getInstance() } returns sdkInstance
}
every { sdkInstance.init() } returns true
mockkStatic(DeviceSDK::class) {
every { DeviceSDK.initialize() } just runs // it fails here 1
}
}
...
}
这在我放置 it fails here 1
注释的地方失败了,因为它调用了我放置 it fails here 2
注释的行,并尝试加载库,给我一个 UnsatisfiedLinkError
.
但我真的不明白为什么,因为首先我在模拟方法 DeviceSDK.initialize()
所以它不应该 运行。但如果它 运行,无论如何我正在模拟 ExternalSDK init
方法,所以也不应该 运行。
有什么地方我没弄对吗?谢谢。
最后,问题是因为 Kotlin 中的 companion objects
实际上并不是静态的 类,即使它们完成了同样的事情。所以你必须把mockkStatic
改成mockkObject
然后它就不会调用SDK了。
我正在尝试向现有的 Android 应用程序添加单元测试,该应用程序具有一些 JNI 库(仅适用于 ARM)。我正在使用 Mockk
和 Junit4
,我有以下内容:
这个静态class是我的,它调用了外部SDK的initialize
方法(给我的,我没有权限访问他们的代码)。
internal class DeviceSDK {
companion object {
internal fun initialize() {
val success = ExternalSDK.getInstance().init() // it fails here 2
return success
}
}
}
init
方法为某些本机库调用 loadLibrary
。
在我的测试中 class,我有以下内容:
class MyDeviceTest {
private val sdkInstance = mockk<ExternalSDK>()
@Before
fun setUp() {
mockkStatic(ExternalSDK::class) {
every { ExternalSDK.getInstance() } returns sdkInstance
}
every { sdkInstance.init() } returns true
mockkStatic(DeviceSDK::class) {
every { DeviceSDK.initialize() } just runs // it fails here 1
}
}
...
}
这在我放置 it fails here 1
注释的地方失败了,因为它调用了我放置 it fails here 2
注释的行,并尝试加载库,给我一个 UnsatisfiedLinkError
.
但我真的不明白为什么,因为首先我在模拟方法 DeviceSDK.initialize()
所以它不应该 运行。但如果它 运行,无论如何我正在模拟 ExternalSDK init
方法,所以也不应该 运行。
有什么地方我没弄对吗?谢谢。
最后,问题是因为 Kotlin 中的 companion objects
实际上并不是静态的 类,即使它们完成了同样的事情。所以你必须把mockkStatic
改成mockkObject
然后它就不会调用SDK了。