JUnitで標準入出力のテスト (Kotlin版)
AtCoderでユニットテストを書くうえで必要になったため、上記リンクを参考にKotlin版を作成しました。以下にサンプルコードを置いておきます。
hr.icon
StandardInputStream.kt
code:kotlin
import java.io.InputStream
class StandardInputStream : InputStream() {
private val sb = StringBuilder()
private val lf = System.getProperty("line.separator")
fun inputln(str: String?) {
sb.append(str).append(lf)
}
override fun read(): Int {
if (sb.length == 0) return -1
sb.deleteCharAt(0)
return result
}
}
StandardOutputStream.kt
code:kotlin
import java.io.*
class StandardOutputStream : PrintStream(ByteArrayOutputStream()) {
private var br = BufferedReader(StringReader(""))
//出力が一行のみでいい場合
fun readLine(): String {
br = BufferedReader(StringReader(out.toString()))
(out as ByteArrayOutputStream).reset()
return br.readLine()
}
//複数行に渡る出力を得たい場合
fun readLines(): List<String> {
val lines = mutableListOf<String>()
br = BufferedReader(StringReader(out.toString()))
(out as ByteArrayOutputStream).reset()
do {
val result = br.readLine()
if (result != null) {
lines.add(result)
}
} while (result != null)
return lines
}
}
sample.kt (実装クラス)
code:kotlin
fun output() {
val str1 = readLine()!!
val str2 = readLine()!!
println(str1)
println(str2)
println(str1 + str2)
}
SampleTest.kt
code:kotlin
import org.hamcrest.CoreMatchers.equalTo
import org.hamcrest.MatcherAssert.assertThat
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
class SampleTest {
private val input = StandardInputStream()
private val output = StandardOutputStream()
@BeforeEach
fun setUp() {
System.setIn(input)
System.setOut(output)
}
@AfterEach
fun tearDown() {
System.setIn(null)
System.setOut(null)
}
@Test
fun output_test() {
input.inputln("foo")
output()
//出力が一行のみの場合はoutput.readLine()でOK. 配列ではなくStringが返却される
val result = output.readLines()
assertThat(result0, equalTo("foo")) assertThat(result1, equalTo("bar")) assertThat(result2, equalTo("foobar")) }
}
以上。
そもそもJVM言語ではなくC系統の言語でやれという話ですが、ちょっと勉強が追いついていないので当面は使い慣れたKotlinで頑張る予定です