JUnit5测试继续运行,不通过也不失败



我有一个类,它有一个方法来添加新的学生对象到数组列表。实例变量通过控制台传递,并验证用户输入(名称不应为空,电话号码应采用正确的格式)。

我想测试一些场景,例如,输入一个有效的名称,不输入任何名称,输入一个有效的电话号码等,但是我不确定如何使用JUnit 5实现这一点。我已经为一个场景编写了一个示例测试,但是当我运行它时,它会陷入运行状态,所以我不确定发生了什么。

我想知道我做错了什么,以及如何改正。

需要测试的类

import java.util.*;
public class Manager {
private ArrayList<Student> students;
Scanner scanner = new Scanner(System.in);
public void addStudent(){
String name;
String mobileNumber;
// Keep prompting the user to enter a value until a non-empty value is entered for the name
while(true) {
System.out.print("Enter student's name: ");
if (scanner.hasNextLine()) {
// Trim leading and trailing whitespace from the value
name = scanner.nextLine().trim();
if (name.length() > 0) {
// A non-empty value was entered
break;
} else {
// An empty value was entered
System.out.println("Error: Student name cannot be left blank");
}
}
}
String phoneRegEx = "^(\+44\s?7\d{3}|\(?07\d{3}\)?)\s?\d{3}\s?\d{3}$";
while (true) {
System.out.print("Enter student's mobile number: ");
mobileNumber = scanner.nextLine();
// Check if the user input matches the phone number format of UK mobile phone numbers
if (mobileNumber.matches(phoneRegEx)) {
break;
} else {
System.out.println("Invalid phone number. Please enter a valid phone number");
}
}
Student student = new Student(name,mobileNumber);
students.add(student);
System.out.println("Student added successfully.n");

}
}

编写的示例测试

@Test
public void addStudentNameTest() {
Manager manager = new Manager();
String testName = "Alice";
String testMobileNumber = "07979931369";
System.setIn(new ByteArrayInputStream((testName + System.lineSeparator() + testMobileNumber).getBytes()));
// Test adding a student with valid input
manager.addStudent();
// Verify that the student was added to the `students` list
assertTrue(manager.getDoctors().size() == 1);
assertEquals(testName, manager.getStudent().get(0).getName());
assertEquals(testMobileNumber, manager.getStudent().get(0).getMobileNumber());
}

问题是在创建Manager实例时创建了Scanner:

public class Manager {
private ArrayList<Student> students;
Scanner scanner = new Scanner(System.in);
//...
}

但是在测试方法中,您首先创建Manager实例,然后才更改System.in:

@Test
public void addStudentNameTest() {
Manager manager = new Manager();
String testName = "Alice";
String testMobileNumber = "07979931369";
System.setIn(new ByteArrayInputStream((testName + System.lineSeparator() + testMobileNumber).getBytes()));
// ...
}

您需要在创建Manager实例之前更改System.in:

@Test
public void addStudentNameTest() {
String testName = "Alice";
String testMobileNumber = "07979931369";
System.setIn(new ByteArrayInputStream((testName + System.lineSeparator() + testMobileNumber).getBytes()));
Manager manager = new Manager();
// ...
}

只有这样做,Manager中的Scanner才能读到改变后的System.in

第一个循环结束,但第二个循环没有结束。这是因为您没有为移动电话号码发送行分隔符。这就像你输入了电话号码,但没有按回车键。

你的两个循环都需要改进以处理无更多输入。如果scanner.hasNextLine()在第一个循环中开始返回false,则该循环将永远不会结束,因为每个迭代器都会跳过整个循环体。如果scanner.hasNextLine()开始返回false,则第二个循环将抛出异常。最好让while条件检查scanner.hasNextLine(),而不是使用true

我是stackoverflow的新用户,我想添加评论,但我没有足够的声誉

我会尽力回答你的问题。

关于你的描述i just guess where it stuck on.

第一个循环

while(true){
//  do something
if(){

}else{}
}

当您输入一个空值时,它将选择else分支,因此它将继续执行do-while

可以在else分支上添加break;

最新更新