2015-04-06 42 views
3

我想为我的主函数编写一个单元测试,其中有一个readLine()循环。如何模拟sc​​ala readLine

我已经尝试了以下是基于java的。我认为readLine()可能需要System.in作为inputStream。但它不起作用。在等待输入的readLine()上阻止ScalaTest。

"readLine" should "work" in { 
    val in = new ByteArrayInputStream("abc".getBytes) 
    System.setIn(in) 
    readLine() === "tester" 
} 

任何想法?谢谢。

+0

我不清楚你的问题到底如何。你在寻找更好的阅读方式吗? io.Source.fromInputStream(...)。getLines可以从输入流中读取,并且非常容易使用或传递不同的流。 –

+0

什么是'readLine' - 是scala.Console或scala.io.StdIn中的弃用方法?或者这是你自己制作的功能?如果是这样,你可以发布源? – childofsoong

+0

@soong,@ rock-fall对不清楚的问题抱歉。我想要做的是集成测试并模拟用户输入以验证我的应用的行为是否正确。由于有一些调用像'console.readLine()'等,我想嘲笑它们,例如在'Inputbuffer'中预先输入一些字符串作为用户输入。然后,readLine()只读取来自'InputBuffer'的输入。 –

回答

3

正确的方法单元测试它是遵循"ports and adapters"模式。

所以你应该有一个接口,它是控制台阅读器的'端口',所以你可以在单元测试中嘲笑它。

此外,您应该有一个集成测试,验证您的'适配器'实际上对真正的控制台工作。

根据你的问题的标题,我想你想做一个集成测试。你几乎在那里。您称为从Scala 2.11.0开始弃用的弃用方法。此代码应该工作 -

"readLine" should "work" in { 
    val in = new ByteArrayInputStream("abc".getBytes) 
    System.setIn(in) 
    StdIn.readLine() === "abc" 
} 
3

Maxim的解决方案实际上不适用于我(再也?)。所以帮助其他人面临同样的问题:

val in = new ByteArrayInputStream(("abc").getBytes) 

Console.withIn(in) { 
    assert(StdIn.readLine() === "abc") 
} 
+0

非常方便。我的sbt测试循环最终坚持要求Maxim提供解决方案。 –