每个 { ... } 块内的 Mockk Missing 调用
Mockk Missing calls inside every { ... } block
我一直在尝试用 mockk 模拟一些东西:
我在 gradle
上进行了以下设置
root:
|-- App (just a sample app for the SDK)
|-- SDK (SDK we develop) << apply plugin: 'com.android.library'
|-- SDKimpl.kt
|-- Foo (wrapper around a .jar library) << apply plugin: 'com.android.library'
|-- Foo.kt
所以我正在为 SDK 编写 androidTest
并尝试模拟 Foo.kt
。
Fooclass没什么异常,直接class Foo(private val someParams) {
所以使用 androidTestImplementation "io.mockk:mockk-android:1.8.13"
模拟:
val mock: Foo = mockk()
// val mock: Foo = mockkClass(Foo::class) // also tried this
every { mock.getData() } returns listOf("1", "2", "3")
我总是遇到以下崩溃:
io.mockk.MockKException: Missing calls inside every { ... } block.
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:42)
也试图收集信息:
- 运行ning 在 JVM 测试文件夹中。它被嘲笑没有问题,但我不能 运行 我的测试作为 JVM
- 运行宁
androidTest
在 Foo
模块内。遇到同样的崩溃
- 使用 mockkClass(Foo::class)。遇到一些崩溃
- 使用注释
@MockK
和 MockKAnnotations.init(this)
。遇到了一些崩溃。
- 在
every {
行之前和 getData()
方法内部添加了 Log.d
,看起来 class 中的实际方法似乎在模拟设置期间被调用。这对我来说太奇怪了。
知道这里出了什么问题吗?
编辑:
根据要求,完整代码。我目前正在处理一个孤立的项目以尝试隔离错误,所以 Foo 只是:
class Foo {
fun getData(): String {
Log.d(TAG, "invoked foo.getData()")
return "trolololo"
}
}
然后我在 androidTest
中有 FooTest:
class FooTest {
@Test
fun mock_foo() {
val foo = mockk<Foo>()
every { foo.getData() } returns "zero"
assertEquals("zero", foo.getData())
}
}
这似乎是一个 Mockk 打开的问题:https://github.com/mockk/mockk/issues/182
2 种可能的快速修复(选择一个):
- 运行 模拟器中的 Instrumented Tests >= Android-P
- 将
Foo
class 设置为开放(以及您想要模拟的方法)
尝试检查 official guide 看看缺少什么。
就我而言,我尝试在 Kotlin 中模拟一个扩展但错过了 mockkStatic
fun Date.asMyTime() : DateTime = DateTime(this, DateTimeZone.getDefault())
mockkStatic("packageName.FileNameKt") // This is what I was missing
every {
DateTime().asMyTime()
} returns mock(DateTime::class.java)
在我的例子中,我忘记了 spyk
我正在申请 every {...}
的 class。
val presenter = spyk(MyPresenter())
every { view.myFun(any()) } returns Unit
就我而言,我错过了
@Before
fun setUp() {
MockKAnnotations.init(this)
}
确保该对象是真正的模拟对象,而不是真实对象。
例如:
- Sdk sdk = Sdk()
+ Sdk sdk = mockk()
every { sdk.crypto } returns mockk()
在我的例子中,我尝试使用 mock() 函数来模拟而不是 mockk() (double k)
这样试试
`when`(mock.getData()).thenReturn(listOf("1", "2", "3"))
我的问题是我使用了 java class 没有 getters
public class KeyStorePasswordPair {
public KeyStore keyStore;
public String keyPassword;
public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
this.keyStore = keyStore;
this.keyPassword = keyPassword;
}
}
我需要为变量添加 getter 以进行模拟工作:
public class KeyStorePasswordPair {
public KeyStore getKeyStore() {
return keyStore;
}
public String getKeyPassword() {
return keyPassword;
}
private KeyStore keyStore;
private String keyPassword;
public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
this.keyStore = keyStore;
this.keyPassword = keyPassword;
}
}
就我而言,@Mock 和 mockk 之间存在冲突。使用其中之一。我认为在 Kotlin 中,最喜欢的是 mockk。
我一直在尝试用 mockk 模拟一些东西:
我在 gradle
上进行了以下设置root:
|-- App (just a sample app for the SDK)
|-- SDK (SDK we develop) << apply plugin: 'com.android.library'
|-- SDKimpl.kt
|-- Foo (wrapper around a .jar library) << apply plugin: 'com.android.library'
|-- Foo.kt
所以我正在为 SDK 编写 androidTest
并尝试模拟 Foo.kt
。
Fooclass没什么异常,直接class Foo(private val someParams) {
所以使用 androidTestImplementation "io.mockk:mockk-android:1.8.13"
模拟:
val mock: Foo = mockk()
// val mock: Foo = mockkClass(Foo::class) // also tried this
every { mock.getData() } returns listOf("1", "2", "3")
我总是遇到以下崩溃:
io.mockk.MockKException: Missing calls inside every { ... } block.
at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:42)
也试图收集信息:
- 运行ning 在 JVM 测试文件夹中。它被嘲笑没有问题,但我不能 运行 我的测试作为 JVM
- 运行宁
androidTest
在Foo
模块内。遇到同样的崩溃 - 使用 mockkClass(Foo::class)。遇到一些崩溃
- 使用注释
@MockK
和MockKAnnotations.init(this)
。遇到了一些崩溃。 - 在
every {
行之前和getData()
方法内部添加了Log.d
,看起来 class 中的实际方法似乎在模拟设置期间被调用。这对我来说太奇怪了。
知道这里出了什么问题吗?
编辑:
根据要求,完整代码。我目前正在处理一个孤立的项目以尝试隔离错误,所以 Foo 只是:
class Foo {
fun getData(): String {
Log.d(TAG, "invoked foo.getData()")
return "trolololo"
}
}
然后我在 androidTest
中有 FooTest:
class FooTest {
@Test
fun mock_foo() {
val foo = mockk<Foo>()
every { foo.getData() } returns "zero"
assertEquals("zero", foo.getData())
}
}
这似乎是一个 Mockk 打开的问题:https://github.com/mockk/mockk/issues/182
2 种可能的快速修复(选择一个):
- 运行 模拟器中的 Instrumented Tests >= Android-P
- 将
Foo
class 设置为开放(以及您想要模拟的方法)
尝试检查 official guide 看看缺少什么。
就我而言,我尝试在 Kotlin 中模拟一个扩展但错过了 mockkStatic
fun Date.asMyTime() : DateTime = DateTime(this, DateTimeZone.getDefault())
mockkStatic("packageName.FileNameKt") // This is what I was missing
every {
DateTime().asMyTime()
} returns mock(DateTime::class.java)
在我的例子中,我忘记了 spyk
我正在申请 every {...}
的 class。
val presenter = spyk(MyPresenter())
every { view.myFun(any()) } returns Unit
就我而言,我错过了
@Before
fun setUp() {
MockKAnnotations.init(this)
}
确保该对象是真正的模拟对象,而不是真实对象。
例如:
- Sdk sdk = Sdk()
+ Sdk sdk = mockk()
every { sdk.crypto } returns mockk()
在我的例子中,我尝试使用 mock() 函数来模拟而不是 mockk() (double k)
这样试试
`when`(mock.getData()).thenReturn(listOf("1", "2", "3"))
我的问题是我使用了 java class 没有 getters
public class KeyStorePasswordPair {
public KeyStore keyStore;
public String keyPassword;
public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
this.keyStore = keyStore;
this.keyPassword = keyPassword;
}
}
我需要为变量添加 getter 以进行模拟工作:
public class KeyStorePasswordPair {
public KeyStore getKeyStore() {
return keyStore;
}
public String getKeyPassword() {
return keyPassword;
}
private KeyStore keyStore;
private String keyPassword;
public KeyStorePasswordPair(KeyStore keyStore, String keyPassword) {
this.keyStore = keyStore;
this.keyPassword = keyPassword;
}
}
就我而言,@Mock 和 mockk 之间存在冲突。使用其中之一。我认为在 Kotlin 中,最喜欢的是 mockk。