【发布时间】:2019-11-12 20:54:11
【问题描述】:
鉴于此代码:
// Subject.kt
open class Subject(var x: Int) {
constructor(): this(42) {
println("made it")
}
fun doit() {
x += 1
println("did it: $x")
}
}
// Tests.kt
import org.junit.jupiter.api.Test
import org.mockito.Mockito
class Tests {
@Test
fun makeit() {
val mock = Mockito.mock(Subject::class.java)
val details = Mockito.mockingDetails(mock)
println("Is mock: ${details.isMock}")
println("Is spy: ${details.isSpy}")
mock.doit()
mock.doit()
}
}
makeit 运行时,输出为:
Is mock: true
Is spy: false
did it: 1
did it: 2
这似乎表明正在创建主题的某些实例,但绕过了潜在的关键构造函数逻辑。这与“部分模拟”是一致的,但是代码并没有做任何事情来请求这样的事情。
我发现这是默认行为令人惊讶,因为文档都强烈警告不要使用部分模拟。我一直无法找到描述 mock() 何时返回部分模拟的文档,因此无法弄清楚如何从类中获取“完整模拟”。
所以:
-
Mockito.mock()何时创建部分模拟? - Mockito 可以为类创建“完整模拟”吗?还是只是为了一个界面?
- 如何请求“完整模拟”?
【问题讨论】:
-
我会将
return of 1解释为该类未被模拟的标志。 (检查你是否看到println。)如果它被嘲笑它应该返回0。 (除非在 kotlin 中有所不同)。部分模拟是使用spy创建的。 -
我更新了问题以显示 Mockito 报告该类已被模拟。我还向
doit添加了第二个调用,以显示“模拟”处于保持状态。 -
我认为这种行为可能与
kotlin不兼容,因此我将其添加为标签。您是否尝试过其他模拟库(mockito-kotlin或mockk)? -
@second:Doh!我们在 Java 中看到了类似的行为(这就是促使我们进行调查的原因)。但果然,上面代码的 Java 版本创建了预期的模拟。我会做一个更好的复制品。谢谢!
-
如果您有一个导致问题的 java 示例,请随时添加一个新问题,包括 minimal reproducible example。
标签: java kotlin mockito partial-mocks