单元测试stdIn / stdOut是否常见?如果是这样,那你将如何测试这样的东西:
import scala.io.StdIn._
object Test {
def main(args: Array[String]) = {
println("Please input your text. Leaving an empty line will indicate end of the input.")
val input = Iterator.continually(readLine()).takeWhile(_ != "").mkString("\n")
val result = doSomethingWithInput(input)
println("Result:")
println(result)
}
}
我通常使用ScalaTest,如果这有任何区别。
答案 0 :(得分:4)
由于Scala在后台使用标准Java流(System.out
,System.in
),您可以通过将自定义流替换标准流来进行测试,您可以进一步检查。 See here了解更多详情。
实际上,虽然我主要关注确保doSomethingWithInput
已经过全面测试,并且可能会跟进输入读数的测试(以确保停止条件和输入字符串构造按预期工作)。 / p>
如果您已经测试过您要访问println
的值,那么确保将其发送到控制台流只会给您带来很多好处。此外,这样的测试案例将是继续前进的痛苦。一如既往,这取决于您的使用案例,但在大多数情况下,我不会对其进行测试。
答案 1 :(得分:0)
我会更改doSomethingWithInput以将BufferedSource作为参数,这样您就可以使用任何源流编写单元测试而不仅仅是stdin
答案 2 :(得分:0)
Console
对象提供了withIn
和withOut
方法,可以临时重定向stdin和stdout。这是一个测试示例vulcanIO
的有效示例,该方法同时读取并打印到stdin / stdout:
import java.io.{ByteArrayOutputStream, StringReader}
import org.scalatest._
import scala.io.StdIn
class HelloSpec extends FlatSpec with Matchers {
def vulcanIO(): Unit = {
println("Welcome to Vulcan. What's your name?")
val name = StdIn.readLine()
println("What planet do you come from?")
val planet = StdIn.readLine()
println(s"Live Long and Prosper ?, $name from $planet.")
}
"Vulcan salute" should "include ?, name, and planet" in {
val inputStr =
"""|Jean-Luc Picard
|Earth
""".stripMargin
val in = new StringReader(inputStr)
val out = new ByteArrayOutputStream()
Console.withOut(out) {
Console.withIn(in) {
vulcanIO()
}
}
out.toString should (include ("?") and include ("Jean-Luc Picard") and include ("Earth"))
}
}
请注意内部重定向的发生方式
Console.withOut(out) {
Console.withIn(in) {
vulcanIO()
}
}
以及我们如何在输出流out
上断言
out.toString should (include ("?") and include ("Jean-Luc Picard") and include ("Earth"))