JUnit test a method that asks for user input - java

I have to test someone elses method that runs endlessly but asks for an input:
public void automatize()
{
String cadena = new String();
while(true)
{
System.out.println("Executing...(Enter command)");
System.out.println("Enter Q to exit");
Scanner sc= new Scanner(new InputStreamReader(System.in));
cadena=sc.nextLine();
if(cadena.toLowerCase().equals("q"))
break;
String[] command = str.split(" ");
if(comando.length!=0)
new Extractor().run(command);
}
}
How am I supposed to test this with JUnit?
This is what I've tried to do, but, well, It doesn't actually do anything:
#Test
public void testAutomatize_q() {
ByteArrayInputStream in = new ByteArrayInputStream("Q".getBytes());
System.setIn(in);
extractor.automatize();
System.setIn(System.in);
}

You can replace System.in with you own stream by calling System.setIn(InputStream in). Input stream can be byte array:
ByteArrayInputStream in = new ByteArrayInputStream("My string".getBytes());
System.setIn(in);
// do your thing
// optionally, reset System.in to its original
System.setIn(System.in)
Different approach can be make this method more testable by passing IN and OUT as parameters:
public static int testUserInput(InputStream in,PrintStream out) {
Scanner keyboard = new Scanner(in);
out.println("Give a number between 1 and 10");
int input = keyboard.nextInt();
while (input < 1 || input > 10) {
out.println("Wrong number, try again.");
input = keyboard.nextInt();
}
return input;
}
Taken from here: JUnit testing with simulated user input

You could use a framework like Mockito in order to mock the Scanner object, and return a fix value when sc.nextLine() is called.
Here's a link of mockito http://mockito.org/, see the 'how' menu to have some examples.

Related

what are the fast ways to take input in java?

In Java i take Input using standard Scanner and BufferedReader Classes like:
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
or
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int a=Integer.parseInt(br.readLine());
but taking input like this takes a lot of running time. I would like to know the faster way to take input. Thanks in advance
Edit: I have seen top java coders like uwi who take input in a very different way. They kinda create their own reader class. I dont get it that how their program becomes fast in runtime.
In the article below, the author discusses three different ways for reading input from the user in the console. Each way is fairly easy to use and also has its own advantages and drawbacks.
The below mechanisms are discussed and examples are provided.
There is also a pros and cons section as well.
Link:
http://www.codejava.net/java-se/file-io/3-ways-for-reading-input-from-the-user-in-the-console
Link:
Most Efficient Way of Taking User Input in Java
Options:
Scanner Class->
Scanner reader = new Scanner(System.in); // Reading from System.in
System.out.println("Enter a number: ");
int n = reader.nextInt();
DataInputStream->
DataInputStream dis = new DataInputStream(System.in);
int i = dis.readInt();
BufferedReader ->
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter your name: ");
String name = reader.readLine();
System.out.println("Your name is: " + name);
Console->
Console console = System.console();
String s = console.readLine();
int i = Integer.parseInt(console.readLine());
Quote from dejavu:
"BufferedReader is a lot faster than Scanner because it buffers the character so you don't have to access the file each time you want to read a char from it.
Scanner are of particular use such as reading primitive data type directly and is also used for regular expressions.
I have used Scanner and BufferedReader both and BufferedReader gives significant fast performance. You can test it yourself too."
from:which to choose buffered reader or scanner from performance point of view
If you want a fast way to input via stdin (and, if I understand you correctly, you want a fast way to repeatedly feed inputs to your programs), your best bet is to pipe or redirect canned responses e.g.
$ java MyReadingClass < mycannedinput.txt
so you can build your class to take interactive input via stdin, and then use a simple shell redirection to feed in canned input such that you don't have to retype it each time.
The Fastest way to take userinput in java in particularly Competitive coding is to make own FastReader class by using bufferedReader and StringTokenizer.
This method uses the time advantage of BufferedReader and StringTokenizer and the advantage of user defined methods for less typing and therefore a faster input altogether. This gets accepted with a time of 1.23 s and this method is very much recommended as it is easy to remember and is fast enough to meet the needs of most of the question in competitive coding.
Implementation :
static class FastReader
{
BufferedReader br;
StringTokenizer st;
public FastReader()
{
br = new BufferedReader(new
InputStreamReader(System.in));
}
String next()
{
while (st == null || !st.hasMoreElements())
{
try
{
st = new StringTokenizer(br.readLine());
}
catch (IOException e)
{
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt()
{
return Integer.parseInt(next());
}
long nextLong()
{
return Long.parseLong(next());
}
double nextDouble()
{
return Double.parseDouble(next());
}
String nextLine()
{
String str = "";
try
{
str = br.readLine();
}
catch (IOException e)
{
e.printStackTrace();
}
return str;
}
}
In Main File :
public static void main(String[] args)
{
FastReader s=new FastReader();
int n = s.nextInt();
int k = s.nextInt();
int count = 0;
while (n-- > 0)
{
int x = s.nextInt();
if (x%k == 0)
count++;
}
System.out.println(count);
}
Source Link : https://www.geeksforgeeks.org/fast-io-in-java-in-competitive-programming/
This is repeated question and an optimized way to read and write data in java can be found at the below link.
https://stackoverflow.com/a/49957378/5076337
These classes are very useful in reading inputs and writing outputs in programming contests.

Why is my String not outputting my value correctly?

I Have a simple program where I just prompt to enter an item and the while loop will continue to ask until I enter the word "end" then it will end the program. When I enter a word like so:
it looks fine, But when I enter 2 words for an item as such I get this output:
notice how when i entered "green yellow" It prompted me after that to enter an item twice?
I can't figure out why it is doing so?
import java.util.Scanner;
public class ToDoListapp {
public static void main(String[] args) /*throws IOException*/ {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("Welome to your TodoList");
boolean keepAdd = true;
String item;
//file
//PrintWriter writeFile = new PrintWriter("TodoList.txt", "UTF-8");
// File file = new File("ToDo.txt");
// BufferedWriter writeTo = new BufferedWriter(new FileWriter(file));
while (keepAdd)
{
System.out.println("Enter an item: ");
item = sc.next();
if (item.equals("end"))
{
keepAdd = false;
}
// writeTo.write(item + "\n");
}
//writeTo.close();
}
}
The default behavior of Scanner is to use whitespace as a delimiter which will be used to break input into tokens. If you just want to use the newline character as a delimiter, try to set the delimiter explicitly.
Scanner sc = new Scanner(System.in);
sc.useDelimiter(System.getProperty("line.separator"));
System.out.println("Welome to your TodoList");
boolean keepAdd = true;
String item;
// The rest of your code
see http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html.
By default it uses any whitespace as the delimiter. So, the call to sc.next() already has its answer with the input green yellow.

Is a scan line escaping?

I've been doing a small project for class, it runs perfectly without problems but when pitted against the class's auto testers it gives back 2 No line found errors. Asking the course's staff they say it's probably because I'm trying to scan a line when none exist, but I tried printing all my scans and didn't discover anything like that.
That's all the scans I have in my code:
Scanner sc = new Scanner(System.in);
String sentence;
int choice;
System.out.println("Please enter a sentence:");
sentence = sc.nextLine();
printMenu(); // calls a function to print the menu.
// gets the require action
System.out.println("Choose option to execute:");
choice = sc.nextInt();
sc.nextLine();
(I tried with and without the last sc.nextLine)
static void replaceStr(String str)
{
String oldWord, newWord;
Scanner in = new Scanner(System.in);
// get the strings
System.out.println("String to replace: ");
oldWord = in.nextLine();
System.out.println("New String: ");
newWord = in.nextLine();
// replace
str = str.replace(oldWord, newWord);
System.out.println("The result is: " + str);
in.close();
}
static void removeNextChars(String str)
{
Scanner in = new Scanner(System.in);
String remStr; // to store the string to replace
String tmpStr = ""; //the string we are going to change.
int i; // to store the location of indexStr
// gets the index
System.out.println("Enter a string: ");
remStr = in.nextLine();
i=str.indexOf(remStr);
in.close(); // bye bye
if (i < 0)
{
System.out.println("The result is: "+str);
return;
}
// Build the new string without the unwanted chars.
/* code that builds new string */
str = tmpStr;
System.out.println("The result is: "+str);
}
Any idea how a line can leak here?
Here is the problem. You are using in.close(); at multiple places(last statement in replaceStr method and around the middle in removeNextChars method). When you close the scnaner using close() method, it closes your InputStream (System.in) as well. That InputStream can't be reopened with-in your program.
public void close() throws IOException --> Closes this input stream and releases any system resources associated with this stream. The general contract of close is that it closes the input stream. A closed stream cannot perform input operations and **cannot be reopened.**
Any read attempts after the scanner close will result into exception NoSuchElementException.
Please close your scanner only once, when your program is done.
EDIT: Scanner Closing/usage:
In yout main function:
Scanner sc = new Scanner(System.in);
....
.....
replaceStr(Scanner sc, String str);
.....
....
removeNextChars(Scanner sc ,String str);
....
....
//In the end
sc.close();
static void replaceStr(Scanner in, String str){
//All the code without scanner instantiation and closing
...
}
static void removeNextChars(Scanner in, String str){
//All the code without scanner instantiation and closing
...
}
You should be all good.

Reading a string with new lines from console java

I want to read this string (from console not file) for example:
one two three
four five six
seven eight nine
So I want to read it per line and put every line in an array.
How can I read it? Because if I use scanner, I can only read one line or one word (nextline or next).
what I mean is to read for example : one two trhee \n four five six \n seven eight nine...
You should do by yourself!
There is a similer example:
public class ReadString {
public static void main (String[] args) {
// prompt the user to enter their name
System.out.print("Enter your name: ");
// open up standard input
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String userName = null;
// read the username from the command-line; need to use try/catch with the
// readLine() method
try {
userName = br.readLine();
} catch (IOException ioe) {
System.out.println("IO error trying to read your name!");
System.exit(1);
}
System.out.println("Thanks for the name, " + userName);
}
} // end of ReadString class
To answer the question as clarified in the comment on the first answer:
You must call Scanner's nextLine() method once for each line you wish to read. This can be accomplished with a loop. The problem you will inevitably encounter is "How do I know big my result array should be?" The answer is that you cannot know if you do not specify it in the input itself. You can modify your programs input specification to require the number of lines to read like so:
3
One Two Three
Four Five
Six Seven Eight
And then you can read the input with this:
Scanner s = new Scanner(System.in);
int numberOfLinesToRead = new Integer(s.nextLine());
String[] result = new String[numberOfLinesToRead];
String line = "";
for(int i = 0; i < numberOfLinesToRead; i++) { // this loop will be run 3 times, as specified in the first line of input
result[i] = s.nextLine(); // each line of the input will be placed into the array.
}
Alternatively you can use a more advanced data structure called an ArrayList. An ArrayList does not have a set length when you create it; you can simply add information to it as needed, making it perfect for reading input when you don't know how much input there is to read. For example, if we used your original example input of:
one two trhee
four five six
seven eight nine
You can read the input with the following code:
Scanner s = new Scanner(System.in);
ArrayList<String> result = new ArrayList<String>();
String line = "";
while((line = s.nextLine()) != null) {
result.add(line);
}
So, rather than creating an array of a fixed length, we can simply .add() each line to the ArrayList as we encounter it in the input. I recommend you read more about ArrayLists before attempting to use them.
tl;dr: You call next() or nextLine() for each line you want to read using a loop.
More information on loops: Java Loops
Look at this code:
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class SearchInputText {
public static void main(String[] args) {
SearchInputText sit = new SearchInputText();
try {
System.out.println("test");
sit.searchFromRecord("input.txt");
System.out.println("test2");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void searchFromRecord(String recordName) throws IOException {
File file = new File(recordName);
Scanner scanner = new Scanner(file);
StringBuilder textFromFile = new StringBuilder();
while (scanner.hasNext()) {
textFromFile.append(scanner.next());
}
scanner.close();
// read input from console, compare the strings and print the result
String word = "";
Scanner scanner2 = new Scanner(System.in);
while (((word = scanner2.nextLine()) != null)
&& !word.equalsIgnoreCase("quit")) {
if (textFromFile.toString().contains(word)) {
System.out.println("The word is on the text file");
} else {
System.out.println("The word " + word
+ " is not on the text file");
}
}
scanner2.close();
}
}

taking integer input in java

I am actually new to java programming and am finding it difficult to take integer input and storing it in variables...i would like it if someone could tell me how to do it or provide with an example like adding two numbers given by the user..
Here's my entry, complete with fairly robust error handling and resource management:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Simple demonstration of a reader
*
* #author jasonmp85
*
*/
public class ReaderClass {
/**
* Reads two integers from standard in and prints their sum
*
* #param args
* unused
*/
public static void main(String[] args) {
// System.in is standard in. It's an InputStream, which means
// the methods on it all deal with reading bytes. We want
// to read characters, so we'll wrap it in an
// InputStreamReader, which can read characters into a buffer
InputStreamReader isReader = new InputStreamReader(System.in);
// but even that's not good enough. BufferedReader will
// buffer the input so we can read line-by-line, freeing
// us from manually getting each character and having
// to deal with things like backspace, etc.
// It wraps our InputStreamReader
BufferedReader reader = new BufferedReader(isReader);
try {
System.out.println("Please enter a number:");
int firstInt = readInt(reader);
System.out.println("Please enter a second number:");
int secondInt = readInt(reader);
// printf uses a format string to print values
System.out.printf("%d + %d = %d",
firstInt, secondInt, firstInt + secondInt);
} catch (IOException ioe) {
// IOException is thrown if a reader error occurs
System.err.println("An error occurred reading from the reader, "
+ ioe);
// exit with a non-zero status to signal failure
System.exit(-1);
} finally {
try {
// the finally block gives us a place to ensure that
// we clean up all our resources, namely our reader
reader.close();
} catch (IOException ioe) {
// but even that might throw an error
System.err.println("An error occurred closing the reader, "
+ ioe);
System.exit(-1);
}
}
}
private static int readInt(BufferedReader reader) throws IOException {
while (true) {
try {
// Integer.parseInt turns a string into an int
return Integer.parseInt(reader.readLine());
} catch (NumberFormatException nfe) {
// but it throws an exception if the String doesn't look
// like any integer it recognizes
System.out.println("That's not a number! Try again.");
}
}
}
}
java.util.Scanner is the best choice for this task.
From the documentation:
For example, this code allows a user to read a number from System.in:
Scanner sc = new Scanner(System.in);
int i = sc.nextInt();
Two lines are all that you need to read an int. Do not underestimate how powerful Scanner is, though. For example, the following code will keep prompting for a number until one is given:
Scanner sc = new Scanner(System.in);
System.out.println("Please enter a number: ");
while (!sc.hasNextInt()) {
System.out.println("A number, please?");
sc.next(); // discard next token, which isn't a valid int
}
int num = sc.nextInt();
System.out.println("Thank you! I received " + num);
That's all you have to write, and thanks to hasNextInt() you won't have to worry about any Integer.parseInt and NumberFormatException at all.
See also
Java Tutorials/Essential Classes/Basic I/O/Scanning and Formatting
Related questions
How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)
How to use Scanner to accept only valid int as input
Other examples
A Scanner can use as its source, among other things, a java.io.File, or a plain String.
Here's an example of using Scanner to tokenize a String and parse into numbers all at once:
Scanner sc = new Scanner("1,2,3,4").useDelimiter(",");
int sum = 0;
while (sc.hasNextInt()) {
sum += sc.nextInt();
}
System.out.println("Sum is " + sum); // prints "Sum is 10"
Here's a slightly more advanced use, using regular expressions:
Scanner sc = new Scanner("OhMyGoodnessHowAreYou?").useDelimiter("(?=[A-Z])");
while (sc.hasNext()) {
System.out.println(sc.next());
} // prints "Oh", "My", "Goodness", "How", "Are", "You?"
As you can see, Scanner is quite powerful! You should prefer it to StringTokenizer, which is now a legacy class.
See also
Java Tutorials/Essential Classes/Regular expressions
regular-expressions.info/Tutorial
Related questions
Scanner vs. StringTokenizer vs. String.Split
you mean input from user
Scanner s = new Scanner(System.in);
System.out.print("Enter a number: ");
int number = s.nextInt();
//process the number
If you are talking about those parameters from the console input, or any other String parameters, use static Integer#parseInt() method to transform them to Integer.

Categories