I am trying to write a junit test to test a method that takes multiple user input. The method takes a person object and sets a rating for them, the first user input is a double value for the rating, the second input is a string with the value "Y" to confirm the change.
I am trying to use ByteArrayInputStream but it is not getting the second input, the error I am getting when i run the test is No line found.
I have identified the problem as I am using different methods to validate user input I have to create a new scanner each time so the second line is not being accepted
Is there a way to set the Scanner again for the second input?
This is my test code
Person p = new Person();
double input1 = 54.3;
String input2 = "Y";
String simulatedUserInput = input1 +
System.getProperty("line.separator")
+ input2 + System.getProperty("line.separator");
System.setIn(new ByteArrayInputStream(simulatedUserInput.getBytes(StandardCharsets.UTF_8)));
addRating(p);
assertEquals(54.3, p.getMyRating(),0);
The method for adding the rating looks like this
public static void addRating(Person p)
{
double rating = Validation.validateRating("Please enter a rating for " + p.getName()); // validate input of double
boolean confirmed = Validation.validateYesNo("Are you sure you wish to set " + p.getName() + "'s rating to " + rating + " Y/N");// confirm yes no
if (confirmed)
{
p.setMyRating(rating);
}
}
Then I have a validation class to ensure correct user input, This is for the rating
public static double validateRating(String str)
{
Scanner in = new Scanner(System.in);
double d = 0;
boolean valid = false;
while (!valid)
{
System.out.println(str);
if (!in.hasNextDouble())
{
System.out.println("Not a valid number");
in.nextLine();
} else
{
d = in.nextDouble();
if(d>=0 && d<=100)
{
valid = true;
}
else
{
System.out.println("Rating must be between 0 and 100");
}
}
}
return d;
}
this is for confirming Y/N input
public static boolean validateYesNo(String str)
{
Scanner in = new Scanner(System.in);
boolean YesNo = false;
boolean valid = false;
while (!valid)
{
System.out.println(str);
String choice = in.next();
if (choice.equalsIgnoreCase("Y"))
{
valid = true;
YesNo = true;
} else if (choice.equalsIgnoreCase("N"))
{
valid = true;
YesNo = false;
} else
{
System.out.println("Invalid input");
}
}
return YesNo;
}
System.setIn(This seems ugly as hell for a unit test. Restructure your code to take an input String as a paramter, and call that method from the unit test. In live code, reading a string and passing it as a parameter is easy, so there's no need to actually testSystem.inany more.