我有一种从流媒体终端下载内容的方法.我想要编写此方法的单元测试.我面临的一个问题是,我需要模拟Kotlin扩展方法file.outputStream(),但我不能模拟 outputStream()kotlin-stdlib FileReadWrite文件中定义如下

@kotlin.internal.InlineOnly
public inline fun File.outputStream(): FileOutputStream {
    return FileOutputStream(this)
}

我的下载方法如下

override fun download(url: String, targetFile: File): Single<File> {
    return Single.fromCallable {
            fileDownloadApi
            .downloadFile(url)
            .execute()
            .body()?.byteStream()?.use { input ->
                targetFile.outputStream().use { output ->
                    FileUtil.copyFile(input, output)
                    return@fromCallable targetFile
                }
            }
        targetFile
    }
}

我需要嘲笑这第targetFile.outputStream()部分. 我正在通过模拟targetFile

我的测试代码就像波罗一样

val mockFileOutputStream = mockk<FileOutputStream>()
val mockTargetFile = mockk<File>()
mockkStatic("kotlin.io.FilesKt")  // declares as JvmName @file:JvmName("FilesKt")
every { File("abc").outputStream() } returns mockFileOutputStream

service.download("", mockTargetFile)
    .subscribe(testObserver)

我嘲笑了file.outputStream()个,建议了official doc个,但得到了错误

io.mockk.MockKException:在每个{. } block:确保块中的对象是mock

对于第every { File("abc").outputStream() } returns mockFileOutputStream

我想不出我错过了什么.请帮我弄清楚这个问题.

推荐答案

请注意,扩展函数是inline.这意味着当您调用它时,并没有实际调用FilesKt中声明的扩展方法.相反,编译器生成直接调用FileOutputStream的构造函数的代码,因为这是outputStream的实现.

因此,您应该嘲笑的是FileOutputStream的构造函数,而不是FilesKt.

例如,

mockkConstructor(FileOutputStream::class) {
    // write the mocks that you would have written for mockFileOutputStream here
    every { anyConstructed<FileOutputStream>().write(...) } just runs
    // and you don't need mockFileOutputStream anymore
}

Kotlin相关问答推荐

在没有外部 map 的情况下转换列表项

Compose:LaunchedEffect在密钥更改后不会重新启动

Kotlin 海峡没有结束

Kotlin Coroutine()是如何工作的?S阻止了.

kotlin - 挂起简单方法调用链时可能存在冗余分支

collectAsState 未从存储库接收更改

始终抛出的函数 - 具有块主体的函数中需要的返回表达式

Kotlin SAM/功能接口抛出 AbstractMethodError

Kotlin 中多个 init 块的用例?

为什么 Kotlin 需要函数引用语法?

在 Kotlin 中取最后 n 个元素

为什么 Dialog 没有 NavController [Missing]?

使用 clear() 删除 EncryptedSharedPreferences 不起作用

如何在 Spring WebFlux 的响应正文中流式传输二进制数据

在用Kotlin编写的Android库公共API中处理R8+JvmStatic Annotation+Lambda

将ExpectedException与Kotlin一起使用

如何在Kotlin中创建无限长的序列

在Kotlin中使用@Service时引发异常

如何限制kotlin协程的最大并发性

如何在 Kotlin 中按字母顺序对字符串进行排序