指定为非空的参数在 Kotlin 函数上使用 Mokito anyObject() 时为 null



我的代码如下,参考 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()

相关内容

  • 没有找到相关文章

最新更新