I have a method to download content from streaming end point. I want to write unit test this method. What I faced a problem is I need to mock kotlin extension method file.outputStream() but I can't mock
outputStream() which is defined in kotlin-stdlib FileReadWrite File as like below
@kotlin.internal.InlineOnly
public inline fun File.outputStream(): FileOutputStream {
return FileOutputStream(this)
}
My download method is like below
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
}
}
I need to mock this part targetFile.outputStream() .
I am passing mock targetFile
My test code is like bolow
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)
I mocked file.outputStream() like official doc suggested but getting error
io.mockk.MockKException: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
for line every { File("abc").outputStream() } returns mockFileOutputStream
I can't figureout what i'm missing. Please help me to figure out this issue.
Notice that the extension function is
inline. This means that when you call it, there is no actual call to the extension method declared inFilesKt. Instead, the compiler generates code that directly calls the constructor ofFileOutputStream, since that is the implementation ofoutputStream.So what you should be mocking is the constructor of
FileOutputStream, notFilesKt.For example,