在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类
这将自动覆盖您的用例,允许所有类别被嘲笑,否则将不被允许。