你好,
我有以下问题:我有一个类,它处理用户交互(输入/输出),我需要为其编写 Junit4 测试。
我想测试的类看起来像这样:
package program;
// imports
public class UserInteraction {
private Program program;
private UserInteraction(){
program = new Program();
}
// Menu display
private void start() {
while (!program.getProgramStarted) {
String input = readInput();
switch (input) {
case "1":
addUser();
break;
case "2":
deleteUser();
break;
case "3":
// ...
default:
System.err.println("Unknown option");
break;
}
}
}
private void addUser() {
// Output
String username = readInput();
program.addUser(username);
System.out.println("User " + username + "added");
}
private void deleteUser() {
// Output
String username = readInput();
program.deleteUser(username);
System.out.println("User " + username + "deleted");
}
@SuppressWarnings("resource")
private String readInput() {
return (new Scanner(System.in)).nextLine();
}
public void main(String[] args) {
UserInteraction ui = new UserInteraction();
ui.start();
}
}
程序类看起来像这样:
package program;
// imports
public class Program {
// fields
private User currentUser;
private List<User> user = new ArrayList<User>();
// constructor
public void addUser(String name) throws Exception {
if (user.size() >= 6) {
throw new Exception();
}
int newID = user.size() + 1;
user.add(new User(name, newID));
}
public String[] getALlUser() {
int counter = 0;
String[] userArray = new String[user.size()];
for (User s : user) {
userArray[counter++] = s.toString();
}
return userArray;
}
}
现在,例如,我想测试以下输入是否被正确处理:
1
John
=> User John added
为此,我编写了一个 Junit 测试,如下所示:
package tests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import org.junit.After;
import org.junit.Test;
import program.*;
public class UserInteractionTest {
private final InputStream originalIn = System.in;
private final PrintStream originalOut = System.out;
private Program program;
@After
public void restoreStreams() {
System.setIn(originalIn);
System.setOut(originalOut);
}
@Test
public void testCreateUser() throws Exception {
String input = "1\nJohn\n";
ByteArrayInputStream in = new ByteArrayInputStream(input.getBytes());
System.setIn(in);
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent)); // Leitet System.out um
program = new Program();
try {
program.main(null);
} finally {
System.setIn(originalIn);
}
String expectedOutput = "User John added";
assertTrue("Output not found", outContent.toString().contains(expectedOutput));
}
}
输入(“1 ") 已完成,但之后没有插入任何输入,因此测试挂起。 有谁知道如何解决这个问题?或者,也许是测试/验证 Java 程序的输入/输出的更好方法?
提前致谢!
我尝试对输入流进行各种修改,例如使用
System.lineSeparator()
而不是 \n
,但问题仍然存在。
直接调用
main
方法并期望整个流程自行发生,本质上并不是单元测试。编写单元测试是为了以隔离的方式测试/验证最小的可执行代码(单元)。这意味着您单独测试方法中的每个流程,将其与外部行为分开。这种隔离通常使用测试替身 (mocks) 来完成
我建议您通过参考官方文档和其他可用资源来正确理解基础知识