qba*_*ait 7 tdd android private kotlin
如何在Kotlin中测试私有方法?我尝试从中添加@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE),androidx.annotation.VisibleForTesting但没有将我的函数设为私有
这就是我的使用方式
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun doSomething() {}
Run Code Online (Sandbox Code Playgroud)
[编辑]
我知道我不应该测试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)
}
}
Run Code Online (Sandbox Code Playgroud)
我为此写了测试
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
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,测试中,我需要调用私有函数fun read(bufferedReader: BufferedReader): List<String>,因为嘲讽时File,file.bufferedReader给出了NullPointerException 无法嘲笑在JUnit的BufferedWriter类
Pio*_*otr 14
您可以使用java反射:
测试方法:
class ClassUnderTest {
private fun printGreetings(name: String): String {
return "Hello, $name"
}
}
Run Code Online (Sandbox Code Playgroud)
这就足够了:
private val classUnderTest = spyk(ClassUnderTest())
@Test
fun `should return greetings`() {
val method = classUnderTest.javaClass.getDeclaredMethod("printGreetings", String::class.java)
method.isAccessible = true
val parameters = arrayOfNulls<Any>(1)
parameters[0] = "Piotr"
assertEquals("Hello, Piotr", method.invoke(classUnderTest, *parameters) )
}
Run Code Online (Sandbox Code Playgroud)
像这样:
fun callPrivate(objectInstance: Any, methodName: String, vararg args: Any?): Any? {
val privateMethod: KFunction<*>? =
objectInstance::class.functions.find { t -> return@find t.name == methodName }
val argList = args.toMutableList()
(argList as ArrayList).add(0, objectInstance)
val argArr = argList.toArray()
privateMethod?.apply {
isAccessible = true
return call(*argArr)
}
?: throw NoSuchMethodException("Method $methodName does not exist in ${objectInstance::class.qualifiedName}")
return null
}
Run Code Online (Sandbox Code Playgroud)
您需要传递要调用该方法的对象的实例、方法名称和所需参数
对此只有一个答案:甚至不要尝试。
您编写源代码来传达意图。如果你做了一些事情,private那么这就是一个内部实现细节。它可能会在下一秒发生变化。
| 归档时间: |
|
| 查看次数: |
4993 次 |
| 最近记录: |