我的代码如下,参考 https://stackoverflow.com/a/30308199/3286489 中的解决方案
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.*
class SimpleClassTest {
private fun <T> anyObject(): T {
Mockito.anyObject<T>()
return uninitialized()
}
private fun <T> uninitialized(): T = null as T
lateinit var simpleObject: SimpleClass
@Mock lateinit var injectedObject: InjectedClass
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun testSimpleFunction() {
simpleObject = SimpleClass(injectedObject)
verify(injectedObject).settingDependentObject(anyObject())
}
}
我仍然有以下错误
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method my.package.InjectedClass.settingDependentObject, parameter dependentObject
我错过了什么吗?
更新以下是测试的代码(最简单的形式和工作)
class SimpleClass(val injectedClass: InjectedClass) {
fun simpleFunction() {
injectedClass.settingDependentObject(DependentClass(Response.Builder().build()))
}
}
open class DependentClass(response: Response) {
}
open class InjectedClass() {
lateinit var dependentObject: DependentClass
fun settingDependentObject(dependentObject: DependentClass) {
this.dependentObject = dependentObject
}
}
默认情况下,Kotlin 类和成员是最终的。Mockito不能模拟最终类或方法。因此,当您编写:
verify(injectedObject).settingDependentObject(anyObject())
调用真正的实现,它需要非空参数。
要解决这个问题,要么打开你的类和方法,要么更好的是,将SimpleClass
更改为接受接口作为其构造函数参数并模拟接口。
有一个项目专门用于帮助处理 Kotlin,使用 Mockito 进行单元测试时"默认关闭"。 对于 JUNIT,您可以使用 kotlin-testrunner,这是一种简单的方法,可以让任何 Kotlin 测试在类加载器加载时自动打开类进行测试。 用法很简单,只需添加一个@RunWith(KotlinTestRunner::class)
注释,例如:
@RunWith(KotlinTestRunner::class)
class MyKotlinTestclass {
@Test
fun test() {
...
}
}
这在文章 永不说最终:在单元测试中嘲笑 Kotlin 类中有详尽的介绍
这以自动的方式涵盖了您的用例,允许模拟所有类,否则将不允许。
我在使用 Mockito 时遇到了同样的问题RETURNS_DEEP_STUBS
.似乎即使使用 kotlin-allopen
插件,嵌套对象仍会返回 null。
如果您遇到同样的问题,请在 Mockito 上查看并评论此问题。
你可以改用这个函数
inline fun <reified T : Any> any(): T = Mockito.any(T::class.java) ?: T::class.java.newInstance()