13

在我们的应用程序中,我们期望用户在 a 中输入Thread如下:

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

我想在我的单元测试中通过那部分,以便我可以恢复线程来执行其余的代码。我怎样才能System.in从junit写一些东西?

4

4 回答 4

29

您要做的是使用setIn()from的方法System。这将让您将数据System.in从 junit 传递到。

于 2010-09-28T14:58:23.437 回答
11

在测试期间更换它:

String data = "the text you want to send";
InputStream testInput = new ByteArrayInputStream( data.getBytes("UTF-8") );
InputStream old = System.in;
try {
    System.setIn( testInput );

    ...
} finally {
    System.setIn( old );
}
于 2010-09-28T14:59:31.657 回答
6

而不是上面的建议(编辑:我注意到 Bart 在评论中也留下了这个想法),我建议通过让类接受输入源作为构造函数参数或类似参数(注入依赖项)来使你的类更具单元测试性. 无论如何,一个类不应该与 System.in 如此耦合。

如果你的类是由 Reader 构建的,你可以这样做:

class SomeUnit {
   private final BufferedReader br;
   public SomeUnit(Reader r) {
       br = new BufferedReader(r);
   }
   //...
}

//in your real code:
SomeUnit unit = new SomeUnit(new InputStreamReader(System.in));

//in your JUnit test (e.g.):
SomeUnit unit = new SomeUnit(new StringReader("here's the input\nline 2"));
于 2010-09-28T15:04:17.433 回答
2

我目前(2018 年)的解决方案是:

 final byte[] passCode = "12343434".getBytes();
 final ByteArrayInputStream inStream = new ByteArrayInputStream(passCode);
        System.setIn(inStream);

[2019 年更新] 对于 JUnit4 测试,这些任务有一个框架: https ://stefanbirkner.github.io/system-rules/(升级到 JUnit5 正在进行中:https ://github.com/stefanbirkner/system -规则/问题/55

于 2018-05-12T09:57:30.410 回答