简单地说,我有一个File
对象,产品代码将在该对象上调用copyTo
方法。
在单元测试中,我只想要一个模拟文件,copyTo调用是一个no-op或者最好是经过验证的。
简单的例子:
fun copyFileTest() {
println("start test")
val mockFileSrc = mock(File::class.java)
val mockFileDst = mock(File::class.java)
`when`(mockFileSrc.exists()).doReturn(true)
`when`(mockFileSrc.copyTo(any(), any(), any())).thenAnswer { // DOES NOT WORK
val result = it.arguments[0]
result as File
}
println("done initializing mocks")
Assert.assertEquals(mockFileSrc.exists(), true)
mockFileSrc.copyTo(mockFileDst, true, 0)
println("done with test")
}
字符串
当单元测试运行时,将引发此异常:
Parameter specified as non-null is null: method kotlin.io.FilesKt__UtilsKt.copyTo, parameter target
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.io.FilesKt__UtilsKt.copyTo, parameter target
at kotlin.io.FilesKt__UtilsKt.copyTo(Utils.kt)
at com.selibe.myapp.foo.WorkerTest.copyFileTest(WorkerTest.kt:121) <34 internal lines>
at jdk.proxy2/jdk.proxy2.$Proxy5.processTestClass(Unknown Source) <7 internal lines>
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74
型
我相信这个问题可能与copyTo
似乎是一个扩展函数有关。
什么是最简单的方法,只是使copyTo在单元测试中的一个空操作,总是成功的单元测试?
mockito或mockk解决方案是可接受的。
3条答案
按热度按时间yebdmbv41#
推荐使用**mockk**库,支持Kotlin扩展函数,Java不支持扩展函数,您正在尝试在代码中使用
extension function
。样品 Package 箱
字符串
您可以根据需要使用其他扩展功能。
您的案例
型
支持@K314159的回答
fnx2tebb2#
你遇到的问题是
File.copyTo
是一个Kotlin extension function。Mockito是一个Java框架,并且不理解任何关于Kotlin扩展函数的东西。Java不支持扩展函数,所以
File.copyTo
实际上在JVM字节码中编译成的是一个静态函数,是类kotlin.io.UtilsKt
的成员,它在参数列表的开头接受一个额外的参数,表示接收者对象(源文件),如下所示:字符串
如果你想使用Mockito来模拟它,你需要在
kotlin.io.UtilsKt
类上使用mockStatic,然后模拟静态方法copyTo
。如果可能的话,切换到为Kotlin编写的mocking框架(如Mockk)会容易得多。使用Mockk时,要模拟模块范围的扩展函数,请按照Mockk网站上的说明使用
mockkStatic
。下面是原始代码的等效代码,已翻译为使用Mockk:型
snz8szmq3#
我肯定不会在这里赢得积分,但我忍不住想知道......为什么你要试图模拟完全可以在单元测试中工作的类?
因为jUnit可以访问Java API和KotlinAPI。
所有你的缓存代码需要JVM投诉是删除硬依赖的android jar.换句话说:
字符串
cacheDir.path是一个String。你的方法应该接收一个String作为参数,而不是直接读取一个android上下文。然后你可以直接运行你的代码,不需要mock,并尝试所有你可能遇到的角落情况。或者对你的代码进行压力测试。
我在我的最新职位上做了这件事。我必须确保4个独立的进程,都能够访问相同的文件和目录,不会在它们之间崩溃。所以我做了一个JVM实现,并将其子类化以添加仅限Android的东西,比如访问上下文。测试同时运行11000个操作。所以我知道它有效。是的,移动和复制文件是测试操作的一部分。而copyTo是我使用的API之一。
记住,你并不依赖于android。你是一个JVM开发者。Android只是你的主要环境。