gpt4 book ai didi

java - 围绕 Sytem.in 和 System.out 进行 JUnit 测试

转载 作者:行者123 更新时间:2023-12-02 07:37:24 24 4
gpt4 key购买 nike

我被要求在从命令行运行和操作的遗留 Java 应用程序中引入单元测试。基本上,主循环打印出一个菜单,用户输入一些内容,它会显示更多数据。

这个主类说明了应用程序的工作原理。

public class Main{

static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

public static void main(String argv[]) throws IOException{
while (true) {
char input = (char) reader.read();

if(input == 'x'){
return;
}

System.out.println(input);
}
}
}

我希望我的测试方法看起来像这样

public void testCaseOne(){
Main.main();
String result = "";

result = sendInput("1");
assertEqual(result, "1");

result = sendInput("x");
assertEqual(result,"");
}

我知道 System.setOut()System.setIn() 方法,但我无法找出使 System. setIn() 方法在此上下文中工作,因为 reader.read() 方法阻塞了我的线程。

我的测试设计是否错误?有没有办法设计 sendInput() 方法来完成阻塞 reader.read() 调用?

最佳答案

我建议重构代码以允许注入(inject)输入/输出流,然后您可以模拟它们。如果你可以将其更改为类似的内容

public class Main{

static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

public static void main(String argv[]) throws IOException{
new YourClass(reader,System.out).run();
}
}

public class YourClass { // I don't know what your class is actually doing, but name it something appropriate
private final InputReader reader;
private final PrintStream output;

public YourClass(InputReader reader, PrintStream output) {
this.reader = reader;
this.output = ouptut;
}

public void run() {

while (true) {
char input = (char) reader.read();

if(input == 'x')
return;

output.println(input);
}
}

这个设计做了几件事:

  1. 它将逻辑从主类中剔除。通常,主方法实际上仅用于启动应用程序。

  2. 它使 YourClass 更容易进行单元测试。在测试中,您可以简单地模拟输入/输出。

编辑:更新此重构如何帮助解决阻塞 IO 问题

通过使读取器/输出可注入(inject),如上所示,您实际上不需要使用真正的 System.in 和 System.out - 您可以使用模拟。这消除了实际阻塞读取的需要。

public void testCaseOne(){
// pseudocode for the mock - this will vary depending on your mock framework
InputReader reader = createMock(InputReader);
// the first time you read it will be a "1", the next time it will be an "x"
expect(reader.read()).andReturn("1");
expect(reader.read()).andReturn("x");

PrintStream stream = createMock(PrintStream);
// only expect the "1" to get written. the "x" is the exit signal
expect(stream.println("1"));

new YourClass(reader,stream).run();
verifyMocks();
}

关于java - 围绕 Sytem.in 和 System.out 进行 JUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15077312/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com