在Kotlin函数中使用Mokito anyObject()时,指定为非null的参数为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接受一个接口作为它的构造函数参数,而不是模拟接口。

有一个项目专门帮助处理与Mockito进行单元测试的“默认关闭”Kotlin。 对于JUNIT,您可以使用kotlin-testrunner ,这是一种简单的方法,可以让任何Kotlin测试自动打开类,以便在类加载器加载时进行测试。 用法很简单,只需添加@RunWith(KotlinTestRunner::class)一个注释,例如:

 @RunWith(KotlinTestRunner::class) class MyKotlinTestclass { @Test fun test() { ... } } 

这篇文章在文章Never say final里被彻底的讲述了:在单元测试中嘲笑Kotlin类

这将自动覆盖您的用例,允许所有类别被嘲笑,否则将不被允许。