【发布时间】:2019-02-01 11:28:24
【问题描述】:
如何在 Kotlin 中测试私有方法?我尝试从androidx.annotation.VisibleForTesting 添加@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE),但它不会使我的函数私有
这就是我的使用方式
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun doSomething() {}
[编辑]
我知道我不应该测试 private 方法,但它现在总是微不足道的。下面的情况呢。
我有一个 CsvReader 类
class CsvReader(private val inputStream: InputStream, private val separator: String = "\t") {
fun read(): List<String> {
return read(inputStream.bufferedReader())
}
private fun read(bufferedReader: BufferedReader): List<String> {
val line = bufferedReader.use { it.readLine() } // `use` is like try-with-resources in Java
return parse(line)
}
private fun parse(line: String): List<String> {
return line.split(separator)
}
}
我为它写了测试
class CsvReaderTest {
private val stream = mock<InputStream>()
private val reader = CsvReader(stream)
private val bufferedReader = mock<BufferedReader>()
@Test
fun read() {
whenever(bufferedReader.readLine()).thenReturn("Jakub\tSzwiec")
reader.read(bufferedReader) shouldEqual listOf("Jakub", "Szwiec")
}
@Test
fun readWhenEmpty() {
whenever(bufferedReader.readLine()).thenReturn("")
reader.read(bufferedReader) shouldEqual listOf("")
}
@Test
fun throwIOExceptionWhenReadingProblems() {
whenever(bufferedReader.readLine()).thenThrow(IOException::class.java)
val read = { reader.read(bufferedReader) }
read shouldThrow IOException::class
}
}
不幸的是,对于测试,我需要调用私有函数 fun read(bufferedReader: BufferedReader): List<String>,因为在模拟 File 时,file.bufferedReader 会给出 NullPointerException Unable to mock BufferedWriter class in junit
【问题讨论】:
-
注解不能使函数成为私有的。它可以帮助 Android Studio 警告您在测试代码之外使用该功能,但仅此而已。
-
您不能直接测试私有方法,也不能通过关键字
private以外的任何其他方式将方法设为私有。要么将它们设为internal,要么只测试公共 API。 -
测试私有函数是一种非常糟糕的做法。始终测试公共 api;不要将您的测试与实现细节联系起来。
-
为了记录:用“,”分割就像 CSV 解析器为您所做的 5%。严肃地说:不要做这样的事情。使用现有的强大 CSV 解析器库。你发明了轮子,你会重复人们在这样做时遇到的所有错误。相信我,我去过那里。正确解析 arbitrary CSV 是hard。
-
我知道@GhostCat。那是面试任务:)
标签: android kotlin tdd private