测试基于控制台的应用程序/程序-Java
全部, 我用Java编写了一个基于命令行的电话簿应用程序。该应用程序基本上要求用户提供一些详细信息,如姓名、年龄、地址和电话号码,并将其存储在文件中。其他操作包括按姓名、电话号码等查找电话簿。所有详细信息都通过控制台输入 我正在尝试为我已经实现的每个功能编写JUnit测试用例,但无法找出如何将实现代码中的测试基于控制台的应用程序/程序-Java,java,command-line,junit,Java,Command Line,Junit,全部, 我用Java编写了一个基于命令行的电话簿应用程序。该应用程序基本上要求用户提供一些详细信息,如姓名、年龄、地址和电话号码,并将其存储在文件中。其他操作包括按姓名、电话号码等查找电话簿。所有详细信息都通过控制台输入 我正在尝试为我已经实现的每个功能编写JUnit测试用例,但无法找出如何将实现代码中的系统重定向到JUnit测试方法中的某个内容,当我的实际代码停止供用户输入时,该方法将提供这些值 例如: 我的实现代码有: BufferedReader is = new BufferedRead
系统重定向到JUnit测试方法中的某个内容,当我的实际代码停止供用户输入时,该方法将提供这些值
例如:
我的实现代码有:
BufferedReader is = new BufferedReader (new InputStreamReader(System.in));
System.out.println("Please enter your name:");
String name = is.readLine(); // My test cases stop at this line. How can I pass command line values i.e. redirect System.in to my test based values?
希望它有意义为什么不编写应用程序,将读取器
作为输入?这样,您就可以轻松地将InputStreamReader(System.in)
替换为FileReader(testFile)
然后是两个例子:
Processor live = new Processor(new InputStreamReader(System.in));
Processor test = new Processor(new FileReader("C:/tmp/tests.txt");
习惯于对界面进行编码将在程序的几乎每个方面带来巨大的好处
还要注意,读取器
是Java程序中处理基于字符输入的惯用方法<代码>输入流
s应保留用于原始字节级处理。(新建)) 我建议您将代码分为三部分:
- 读取输入(如示例中的
)name
- 用这些输入做你需要做的事情
- 打印结果
name
。如果这是唯一的参数,那么创建一个方法——我们称之为nameConsumer
——使用该名称,执行某些操作并返回其结果。在单元测试中,执行以下操作:
@Test
public void testNameConsumer() {
// Prepare inputs
String name = "Jon";
String result = nameConsumer(name);
assertEquals("Doe", result);
}
将您的println
和readLine
调用移动到其他方法,并在namecuster
周围使用,但不要在单元测试中使用
public class YourAppTest {
@Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream();
@Test
public void test() {
systemInMock.provideText("name\nsomething else\n");
YourApp.main();
//assertSomething
}
}
请在此处阅读更多信息:
- 例如,但仍然:
public class YourAppTest {
@Rule
public TextFromStandardInputStream systemInMock = emptyStandardInputStream();
@Test
public void test() {
systemInMock.provideText("name\nsomething else\n");
YourApp.main();
//assertSomething
}
}
有关详细信息,请查看。这需要一个测试,并使用来自的想法使其可测试
班级本身:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
public class TestableLoopingConsoleExample {
public static final String INPUT_LINE_PREFIX = "> ";
public static final String EXIT_COMMAND = "exit";
public static final String RESPONSE_PLACEHOLDER = "...response goes here...";
public static final String EXIT_RESPONSE = "Exiting.";
public static void main(String[] cmdLineParams_ignored) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintStream out = new PrintStream(System.out);
PrintStream err = new PrintStream(System.err);
try {
new TestableLoopingConsoleExample().main(cmdLineParams_ignored, in, out);
} catch (Exception e) { //For real use, catch only the exactly expected types
err.println(e.toString());
}
}
……继续
public void main(String[] cmdLineParams_ignored, BufferedReader in, PrintStream out)
throws IOException {
System.out.println("Enter some text, or '" + EXIT_COMMAND + "' to quit");
while (true) {
out.print(INPUT_LINE_PREFIX);
String input = in.readLine();
out.println(input);
if (input.length() == EXIT_COMMAND.length() &&
input.toLowerCase().equals(EXIT_COMMAND)) {
out.println(EXIT_RESPONSE);
return;
}
out.println(RESPONSE_PLACEHOLDER);
}
}
}
@Test
public void testableMain_validInputFromString_outputAsExpected() throws Exception {
String line1 = "input line 1\n";
String line2 = "input line 2\n";
String line3 = "input line 3\n";
String exitLine = EXIT_COMMAND + "\n";
BufferedReader in = new BufferedReader(new StringReader(
line1 + line2 + line3 + exitLine
));
String expectedOutput =
INPUT_LINE_PREFIX + line1 +
RESPONSE_PLACEHOLDER + "\n" +
INPUT_LINE_PREFIX + line2 +
RESPONSE_PLACEHOLDER + "\n" +
INPUT_LINE_PREFIX + line3 +
RESPONSE_PLACEHOLDER + "\n" +
INPUT_LINE_PREFIX + exitLine +
EXIT_RESPONSE + "\n";
String[] ignoredCommandLineParams = null;
new TestableLoopingConsoleExample().main(ignoredCommandLineParams, in, new PrintStream(out));
assertEquals(expectedOutput, out.toString());
}
}
测试(JUnit4):
……继续
public void main(String[] cmdLineParams_ignored, BufferedReader in, PrintStream out)
throws IOException {
System.out.println("Enter some text, or '" + EXIT_COMMAND + "' to quit");
while (true) {
out.print(INPUT_LINE_PREFIX);
String input = in.readLine();
out.println(input);
if (input.length() == EXIT_COMMAND.length() &&
input.toLowerCase().equals(EXIT_COMMAND)) {
out.println(EXIT_RESPONSE);
return;
}
out.println(RESPONSE_PLACEHOLDER);
}
}
}
@Test
public void testableMain_validInputFromString_outputAsExpected() throws Exception {
String line1 = "input line 1\n";
String line2 = "input line 2\n";
String line3 = "input line 3\n";
String exitLine = EXIT_COMMAND + "\n";
BufferedReader in = new BufferedReader(new StringReader(
line1 + line2 + line3 + exitLine
));
String expectedOutput =
INPUT_LINE_PREFIX + line1 +
RESPONSE_PLACEHOLDER + "\n" +
INPUT_LINE_PREFIX + line2 +
RESPONSE_PLACEHOLDER + "\n" +
INPUT_LINE_PREFIX + line3 +
RESPONSE_PLACEHOLDER + "\n" +
INPUT_LINE_PREFIX + exitLine +
EXIT_RESPONSE + "\n";
String[] ignoredCommandLineParams = null;
new TestableLoopingConsoleExample().main(ignoredCommandLineParams, in, new PrintStream(out));
assertEquals(expectedOutput, out.toString());
}
}
我不明白你的意思。在我的示例中,上面发布的代码是如何工作的?因此,如果我必须在测试方法中传递命令行值,我必须使用文件
tests.txt
?如果是这样,我希望通过我的测试方法传递值,而不是创建文件来传递值。这两个读取器具有相同的接口。单元测试使用FileReader
,因为它不需要用户输入(准备文本文件是为了测试不同的输入)。您使用InputStreamReader(System.in)
进行实时执行程序,因此它仍然会直接请求用户输入。请详细说明您的答案好吗?为什么我要使用文件“input.txt”?@darkie15:这只是一个例子。@darkie15:你也可以使用PipedInputStream
和PipedOutputStream
等等。你可以找到一些示例代码来实现你在这里描述的内容:但这基本上只是一种实现oxbow_lakes在回答中描述的内容的方法。非常有用的库!在这里使用它: