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

时间:2016-05-21 06:28:26

标签: mockito kotlin

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

4 个答案:

答案 0 :(得分:10)

默认情况下,Kotlin classes and members are final 。 Mockito cannot mock final classes or methods。 因此当你写:

verify(injectedObject).settingDependentObject(anyObject())

真实实现称为,需要非空参数。

要修复打开您的类和方法,或者更好的是,更改SimpleClass以接受接口作为其构造函数参数并改为模拟接口。

答案 1 :(得分:1)

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

@RunWith(KotlinTestRunner::class)

Never say final: mocking Kotlin classes in unit tests

一文中详细介绍了这一点

这允许以自动方式覆盖您的用例,允许所有类被模拟,否则将不被允许。

答案 2 :(得分:0)

使用RETURNS_DEEP_STUBS时,我遇到了与Mockito相同的问题。即使使用kotlin-allopen插件,似乎仍会为嵌套对象返回空值。

如果您遇到同样的问题,请查看并评论Mockito上的this issue

答案 3 :(得分:0)

您可以改用此功能

Component.prototype.createOperations = function()
{
    component.createOperations();
    if (systemInfo.productType === "windows") {
        component.addOperation("CreateShortcut", "@TargetDir@\\app.exe", "@StartMenuDir@/app.lnk","iconPath=@TargetDir@\\icon.ico");
    }
}