[英]Redirected System.in ByteArrayInputStream is read one JUnit test too late
I am Currently writing Junit tests for automated testing of student tasks.我目前正在编写 Junit 测试,用于自动测试学生任务。 The topic is console input in java.
主题是 java 中的控制台输入。 I have multiple tests that need to take simulated user input and check for correct behaviour of tested methods (method is working fine).
我有多个测试需要模拟用户输入并检查测试方法的正确行为(方法工作正常)。
My problem at the moment: the ByteArrayInputStream set as System.in
won't release when needed but one test later (see pic below).我目前的问题:设置为
System.in
的 ByteArrayInputStream 不会在需要时发布,但稍后会进行一次测试(见下图)。
I tried to reset the stream, make it static, make it non-static, have standard System.in
set before and after, tried read method, switched java-versions (from SE13 to 1.8).我尝试重置 stream,使其成为 static,使其成为非静态,前后设置标准
System.in
,尝试读取方法,切换 java 版本(从 SE13 到 1.8)。 All attempts at different times, ofc.不同时间的所有尝试,ofc。
Explanation of output in the picture:图中output说明:
It's from our automated JUnit-Framework.它来自我们的自动化 JUnit 框架。 Those are two tests reliant on the tested method that takes a user input.
这两个测试依赖于接受用户输入的测试方法。 The "?"
这 ”?” at the start of a line indicate the tested method is active and waiting.
在一行的开头表示测试的方法处于活动状态并正在等待。 First two words after the STARTING TEST line are what is supposed to get injected.
STARTING TEST 行之后的前两个单词应该被注入。
JUnit test code: JUnit 测试代码:
final static InputStream STDIN = System.in;
static ByteArrayInputStream bais;
final static String[] INJECTIONS = { "abc", "def", "ghi", "jkl", "mmmm", "klopp", "urgl", "gurle", "ding", "dong" };
private static void inject(String injection, Object o, MethodSignature ms) {
System.out.println(injection);
try {
ByteArrayInputStream bais = new ByteArrayInputStream(injection.getBytes("UTF-8"));
System.setIn(bais);
System.out.println("Injection Bytes: "+injection.getBytes().length);
System.out.println("Available for injection: " + System.in.available());
ms.getMethod().invoke(o);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.setIn(STDIN);
}
}
private static String getStringInject(String injection, Object o, MethodSignature ms) {
String out = null;
System.out.println(injection);
try {
ByteArrayInputStream bais = new ByteArrayInputStream(injection.getBytes("UTF-8"));
System.setIn(bais);
System.out.println("Injection Bytes: "+injection.getBytes().length);
System.out.println("Available for injection: " + System.in.available());
System.in.reset();
out = (String) ms.getMethod().invoke(o);
} catch (Exception e) {
e.printStackTrace();
}
finally {
System.setIn(STDIN);
}
return out;
}
@Test
public void checkReadFromConsoleCorrectReturnTest() {
Object o = createObject(csMain.getC());
if (o == null) {
addFail(csMain.getObjectFail());
return;
}
String injection = INJECTIONS[ThreadLocalRandom.current().nextInt(0, INJECTIONS.length)];
String output = getStringInject(injection + System.lineSeparator() + "END" + System.lineSeparator(), o,
msReadFromConsole);
if (output == null || output.isEmpty()) {
addFail(msReadFromConsole.getMethodNoReturnString());
return;
}
}
@Test
public void checkReadCorrectEndingTriggerTest() {
Object o = createObject(csMain.getC());
if (o == null) {
addFail(csMain.getObjectFail());
return;
}
String injection = INJECTIONS[ThreadLocalRandom.current().nextInt(0, INJECTIONS.length)]
+ System.lineSeparator() + "END" + System.lineSeparator();
inject(injection, o, msRead);
}
Tested java methods:测试 java 方法:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class ConsoleReader implements IConsoleReader {
ArrayList<String> reads;
BufferedReader br;
public ConsoleReader() {
reads = new ArrayList<String>();
br = new BufferedReader(new InputStreamReader(System.in));
}
public void read() {
String input = readFromConsole();
while (true) {
if (input == null || input.isEmpty()) {
System.out.println("ERROR: null");
return;
}
input = input.trim().toUpperCase();
if (input.equals("END")) {
System.out.println("Done.");
return;
}
reads.add(input);
input = readFromConsole();
}
}
public String readFromConsole() {
System.out.print("? ");
String out = null;
try {
out = br.readLine();
} catch (Exception e) {
e.printStackTrace();
return null;
}
System.out.println(out);
return out;
}
}
Help is much appreciated.非常感谢您的帮助。 Can't change the Junit library used or add other external libraries atm.
无法更改使用的 Junit 库或添加其他外部库 atm。
I wrote the following snippet for you to run:我编写了以下代码段供您运行:
@Test
public void test_byteArrayInputStream() {
InputStream STDIN = System.in;
String message = "test" + System.lineSeparator();
try (ByteArrayInputStream in = new ByteArrayInputStream(message.getBytes("UTF-8"))) {
System.setIn(in);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
assertEquals("test", br.readLine()); // this succeeds
} catch (IOException e) {
e.printStackTrace();
} finally {
System.setIn(STDIN);
}
}
As you can see, the BufferedReader
correctly ready "test"
from the in stream.如您所见,
BufferedReader
从 stream 中正确准备好"test"
。 I used the AutoClosable
aspect of ByteArrayInputStream
to close it after the code block.我使用
ByteArrayInputStream
的AutoClosable
方面在代码块之后关闭它。
Since this does not solve your problem, I am uncertain whether the problem does not originate in the surrounding framework.由于这不能解决您的问题,因此我不确定问题是否源于周围的框架。 More specifically, the only explanation I can think of for the leap over of values from Testcase 1 to Testcase 2 is, that the object is not reinstantiated, but reused somehow.
更具体地说,对于从测试用例 1 到测试用例 2 的值的跨越,我能想到的唯一解释是,object 没有重新实例化,而是以某种方式重用。 Since this code is missing, it cannot be said for sure.
由于缺少此代码,因此无法确定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.