I'm currently writing some JUnit tests for some assignments on Replit.com's Teams for education. I have a test that's getting stuck, I believe, because of a while loop in the main method. If the first input is valid, according to the program, the test runs. If the first input is invalid, the test gets stuck.
Here's the test:
@Test
public void validPW(){
String correctOutput = "Enter a password >> Not enough uppercase letters!\nNot enough digits!\nReEnter a password >> Valid password\nGoodbye!";
try{
// IMPORTANT: Save the old System.out!
PrintStream old = System.out;
// Create a stream to hold the output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//PrintStream ps = new PrintStream(baos);
System.setOut(new PrintStream(baos, false, "UTF-8"));
// IMPORTANT: save old Sytem.in!
InputStream is = System.in;
// Set new System.in
System.setIn(new ByteArrayInputStream("Iljvm4\nVaGN76js\n".getBytes()));
// Calling main method should save main method's output as string literal to baos.
String[] requiredArray = {"Hello", "There"};
ValidatePassword.main(requiredArray);
// Put things back
System.out.flush();
System.setOut(old);
//Restore
System.setIn(is);
assertEquals(correctOutput, baos.toString());
}catch(IOException ioe){
new IOException("i/o problem - test not executed\n");
}
}
Here's the program:
import java.util.*;
public class ValidatePassword {
public static void main(String[] args) {
String passWord;
boolean Valid = false;
final int NUM = 2; // two digits and two Upper case letters
// counters to count the required digits and letters
int upperCount = 0;
int lowerCount = 0;
int digitCount = 0;
while (!Valid) {
Scanner in = new Scanner(System.in);
int numSpaces = 0;
System.out.print("Enter a password >> ");
passWord = in.next();
in.nextLine(); // capture dangling newline char.
// Using a for loop to iterate over each character in the String
for (int i = 0; i < passWord.length(); i++) {
char ch = passWord.charAt(i);
if (Character.isUpperCase(ch)){ // Using the Character class's methods
upperCount++;
}
else if (Character.isLowerCase(ch)){
lowerCount++;
}
else if (Character.isDigit(ch)){
digitCount++;
}
}
if (upperCount >= NUM && lowerCount >= 3 && digitCount >= NUM) {
System.out.println("Valid password\nGoodbye!");
Valid = true;
} else {
if (upperCount < NUM)
System.out.println("Not enough uppercase letters!");
if (lowerCount < 3)
System.out.println("Not enough lowercase letters!");
if (digitCount < NUM)
System.out.println("Not enough digits!");
System.out.print("Re");
// Resetting the counters if not a valid password
upperCount = 0;
lowerCount = 0;
digitCount = 0;
}
}
}
}