I have a class that has a method to add new student objects into an arraylist. The instance variables are passed through the console and the user input is validated (name should not be empty, phone number should be in the correct format).
I want to test scenarios such as, entering a valid name, not entering any name, enterting a valid phone number etc, but I'm not sure how to achieve this using JUnit 5. I have written a sample test for one scenario, but when I run it, it gets stuck in the running state so I am not sure what is happening as well.
I want to know what I am doing wrong and how I can rectify it.
The Class that needs to be tested
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");
}
}
Sample test written
@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());
}
CodePudding user response:
The first loop ends, but the second one doesn't. That's because you're not sending a line separator for the mobile phone number. It's like you entered the phone number but didn't press enter.
Both of your loops need to improved to handle no-more input. If scanner.hasNextLine()
starts returning false
while still in the first loop, that loop will never end, because the entire loop body will be skipped for each iterator. Your second loop will instead throw an exception if scanner.hasNextLine()
starts returning false
. It's better to let both while
conditions check for scanner.hasNextLine()
instead of using true
.
CodePudding user response:
im a newcommer on stackoverflow, i want to add a comment but i haven't enough reputation
I will try my best to ans your question.
On your describe i just guess where it stuck on
.
In the first loop
while(true){
// do something
if(){
}else{}
}
When you enter a empty value, it will choise else branch, so it contine to do-while
You can add break;
on the else branch.