How can I unit test user input in java - java

I am trying to understand how can I test a user's input (please note I am not trying to do a mock test but a test of actual user's input)
Currently as you may see in my program I have hard coded the values for my test case and it is passing all tests but how can I get a user's input and test it .
Is there a way where I can call System.in my constructor and pass it when I create an instance of MyClass1 in the test class?
Please, if possible give me some example code so I can better understand.
If I have a interface as such
public interface IMyClass{
public int getvalue1();
public int getvalue2();
public int getvalue3();
}
and then interface implementation as such
public class MyClass1 implements MyClass{
private int _value1 = 0;
private int _value2 = 0;
private int _value3 = 0;
public MyClass1(int number1, int number2, int number3)
{
_value1 = number1;
_value2 = number2;
_value3 = number3;
}
public void setLength1(int value1)
{
_value1 = value1;
}
public void setLength2(int length2)
{
_value2 = value2;
}
public void setLength3(int length3)
{
_value3 = value3;
}
public int getValue1()
{
return _value1;
}
public int getValue2()
{
return _value2;
}
public int getValue3()
{
return _value3;
}
}
and finally a test class as such:
public class ClasTest extends TestCase {
public void testNumbers()
{
MyClass1 numbers= new MyClass1(1,2,3);
assertThat(numbers.getValue1(),is(not(numbers.getValue2())));
}
}
Thankyou, I appreciate any help.

Use System.setIn(new InputSteam()); and then write to the input stream passed in to System.in
see: JUnit: How to simulate System.in testing?
Single Input
String data = "Users Input";
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.nextLine());
Result
Users Input
Multiple Inputs
String data = "Users Input" +
"\nA second line of user input.";
System.setIn(new ByteArrayInputStream(data.getBytes()));
Scanner scanner = new Scanner(System.in);
System.out.println("Line 1: " + scanner.nextLine());
System.out.println("Line 2: " + scanner.nextLine());
Result
Line 1: Users Input
Line 2: A second line of user input.

If on unix
java MyProgram < sampleinput.txt

user Scanner class
public void testNumbers()
{
Scanner scan = new Scanner(System.in);
System.out.println("value1");
int value1 = scan.nextInt();
System.out.println("value2");
int value2 = scan.nextInt();
System.out.println("value3");
int value3 = scan.nextInt();
MyClass1 numbers= new MyClass1(value1, value2, value3);
assertThat(numbers.getValue1(),is(not(numbers.getValue2())));
}

Related

Changing and using one object array in two methods

I'm making a phone class and a phone book class right now. The phone class declares name and phone number fields, and the phone book class has read and run methods. When run() method is executed in the main function, information is input through the read() method, and information is retrieved and output through the run() method. However, I declared an instance array called phonebooks and tried to input the information received from the read() method into the array, but when I tried to output it through the run method, the array instances were not saved properly. There seems to be an issue where something isn't saving properly, how do I fix it?
import java.util.Scanner;
class Phone {
static private String name;
static private String tel;
public String getNum() {
return tel;
}
public String getName() {
return name;
}
public Phone(String name, String tel) {
this.name = name;
this.tel = tel;
}
}
public class PhoneBook {
private Scanner scanner;
static int repeat;
static Phone[] phonebooks;
public PhoneBook() {
scanner = new Scanner(System.in);
}
void read() {
System.out.print("Number of person to store? >> ");
int repeat = scanner.nextInt();
Phone[] phonebooks = new Phone[repeat];
for (int i = 0; i < repeat; i++) {
System.out.print("Name and Tel. No. >> ");
String name = scanner.next();
String tel = scanner.next();
phonebooks[i] = new Phone(name, tel);
if (i == repeat - 1) break;
}
System.out.println("Saved.");
}
void run() {
read();
while (true) {
System.out.print("Who do you wanna search for? >> ");
String search = scanner.next();
if (search.equals("stop")) break;
int i;
for (i = 0; i < repeat; i++) {
if (phonebooks[i].getName() == search)
System.out.println(search + "'s number is " + phonebooks[i].getNum());
break;
}
}
scanner.close();
}
public static void main(String[] args) {
new PhoneBook().run();
}
}
There are few issues in your code, below are some suggestions to make it work--
change member variables from static private to only private in Phone
Don't redeclare repeat & phonebooks in read().
Change if (phonebooks[i].getName() == search) call in run() to if (phonebooks[i].getName().equalsIgnoreCase(search)) so that it will search & match search string.

User input and object creation inside method

I have a Java Class named Real
public class Real {
private long wholeNumPart;
private long decimalPart;
public Real(){
wholeNumPart =0;
decimalPart=0;
}
public Real(long wholeNumPart, long decimalPart) {
this.wholeNumPart =wholeNumPart;
this.decimalPart = decimalPart;
}
public long getWholeNumPart() {
return wholeNumPart;
}
public long getDecimalPart() {
return decimalPart;
}}
I have another class name RealApplication where I need to create two methods
createRealObject() that allows a user to input a real number and creates an object representing
that number.
2.createRealNumber() which accepts an object of type Real and returns a real number represented
by that object.
I am having difficulty creating these two methods
Here is what I've done so far
import java.util.Scanner;
public class RealApplication {
public void createRealNumber() {
Scanner sc=new Scanner(System.in);
//Allows user input
System.out.print("Please, enter a real number: ");
long n = sc.nextLong();
//Creates Real object ( is this correct????)
Real in = new Real();
}
public long createRealNumber(Real num) {
long realNum=0;
//I do not know what to write here :(
return realNum;
}
}
Your Real class looks good with some changes in the RealApplication class we can achieve what you want:
import java.util.Scanner;
public class RealApplication {
public static Real createRealObject() {
Scanner sc=new Scanner(System.in);
//Allows user input
System.out.print("Please, enter a real number: ");
String n = sc.nextLine();
String[] pieces = n.split("[.,]+"); //special pattern to recognize comma and dot
long wholeNumPart;
long decimalPart;
try {
wholeNumPart = Long.valueOf(pieces[0]);
decimalPart = Long.valueOf(pieces[1]);
}
catch (NumberFormatException e) {
System.out.println("You should enter a number!");
return null;
}
Real in = new Real(wholeNumPart, decimalPart);
sc.close();
return in;
}
The important point is that I declared the both methods as static in this way you can use the methods without creating an instance of RealApplication class.
You should use "double" primitive type to store fractional numbers not "long". Now the method that returns the number equivalent of that object:
public static double createRealNumber(Real num) {
double realNum;
long wholeNumPart = num.getWholeNumPart();
long decimalPart = num.getDecimalPart();
int numOfDigits = (int)(Math.log10(decimalPart)+1);
realNum = wholeNumPart + (decimalPart / Math.pow(10,numOfDigits));
return realNum;
}
And if we write a main method:
public class Main {
public static void main(String[] args) {
Real realObj = new Real(10,2323232);
double number = RealApplication.createRealNumber(realObj);
System.out.println("Equivalent number for the object: " + number);
Real newObj = RealApplication.createRealObject();
if (newObj != null) {
System.out.println("New object's number part: " + newObj.getWholeNumPart());
System.out.println("New object's decimal part: " + newObj.getDecimalPart());
}
else{
return;
}
}
}
Because of the regex pattern we used, the inputs separated with "." and "," are allowed like 10.23 10,23 .

Catching results from a void method into an output file

I am new at Java so thank you for helping!
public static int convert (String value) {
int temp_convert = 0;
// Setting up new Scanner to read the User-input string
Scanner token = new Scanner(value);
// Take out the word "CONVERT"
String fnc = token.next();
// Get the temperature that needs to be converted
int temp = token.nextInt();
// Current unit of temperature
String type = token.next().toLowerCase();
if (type.equals("f")) {
temp_convert = (int) Math.round((temp - 32)/1.8);
System.out.println(temp_convert + "C");
} else if (type.equals("c")) {
temp_convert = (int) Math.round(1.8 * temp + 32);
System.out.println(temp_convert + "F");
}
return temp_convert;
}
I am trying to get the print result from this method into an output file using PrintStream. I need whatever is lines printed in this method to be print out into the output file. How can I do this? This is the code I have so far but it doesn't produce anything in the .txt file yet.
public static void readFile (Scanner console, String file_input) throws FileNotFoundException {
// Setting up new Scanner to scan the file
Scanner input = new Scanner (file_input);
// Prompt user for output file's name
System.out.print("Output file name: ");
String name_output = console.next();
PrintStream file_output = new PrintStream(new File(name_output));
System.out.println("YazLang program interpreted and output to .txt file!");
System.out.println();
while (input.hasNext()) {
String value = input.nextLine().toLowerCase();
if (value.startsWith("convert")) {
int concert_temp = convert(value);
file_output.println(concert_temp);
} else if (value.startsWith("range")) {
range(value);
} else if (value.startsWith("repeat")) {
repeat(value);
}
}
}
Why don't you change signature of convert method to return int?
public static int convert (String value) {
Scanner token = new Scanner(value);
// ...
return value;
}
And then write result to file in readFile method like this:
public static void readFile (Scanner console, String file_input) throws FileNotFoundException {
// omitted..
while (input.hasNext()) {
String value = input.nextLine().toLowerCase();
if (value.startsWith("convert")) {
int concert_temp = convert(value);
file_output.println(concert_temp);
} else if (value.startsWith("range")) {
// here
int concert_temp = range(value);
file_output.println(concert_temp);
} else if (value.startsWith("repeat")) {
repeat(value);
}
}
}
you can use System.setOut() (https://www.tutorialspoint.com/java/lang/system_setout.htm)
Insert this line after line 7 in your readFile method:
System.setOut(file_output);
There are two options:
Define the PrintStream in the outer most function, then pass it to whichever function you need. Proceed to write to file using PrintStream::print... method.
Define a wrapper class that will write to both stream:
public class DuplexPrinter {
private final PrintStream printStream;
public DuplexPrinter(PrintStream printStream) {
this.printStream = printStream;
}
public void println(String line) {
System.out.println(line);
printStream.println(line);
}
public void close() {
printStream.close();;
}
}
Init printer:
DuplexPrinter printer = new DuplexPrinter(file_output);
Now replace every call to System.out.println with:
printer.println()
Using third party library. For example TeeOutputStream

My bot program accepts user input and then instead of replying, does nothing

I created a bot and used a snippet of code I invented called "simplify" to dramatically shorten java commands.
Only problem is, the bot program I made with it doesn't work. It's supposed to search the user input for keywords and reply accordingly, but all it really does is accept user input and then turn off. What did I do wrong?
import java.util.*;
public class bot{
//"simplify" and "bot" created by #genisome, All rights reserved.
System.out.println(in);
}
public static void print(String in){
System.out.println(in);
}
public static void print(double in){
System.out.println(in);
}
public static void print(long in){
System.out.println(in);
}
public static void print(boolean in){
System.out.println(in);
}
public static void print(float in){
System.out.println(in);
}
//scan below
public static void scan(int dumpinto){
Scanner x = new Scanner(System.in);
dumpinto = x.nextInt();
}
public static void scan(String dumpinto){
Scanner x = new Scanner(System.in);
dumpinto = x.next();
}
public static void scan(double dumpinto){
Scanner x = new Scanner(System.in);
dumpinto = x.nextDouble();
}
public static void scan(float dumpinto){
Scanner x = new Scanner(System.in);
dumpinto = x.nextFloat();
}
public static void scan(boolean dumpinto){
Scanner x = new Scanner(System.in);
dumpinto = x.nextBoolean();
}
public static void random(int min, int max, int dumpinto){
Random x = new Random();
dumpinto = x.nextInt(max) + min;
}
public static void main (String[] x){
int score;
String[] badcomputerresponse = {"that sucks, sorry", "sorry about that", "bummer", "shit", "aw, damn"};
String[] goodcomputerresponse = {"awesome.", "me too", "great", "cool", "I'm not bad myself"};
String[] goodwords = {"good", "fine", "dandy", "awesome", "cool", "swell", "great", "amazing", "ok", "okay", "well", "happy", "thrilled"};
String[] badwords = {"shitty", "terrible", "sad", "bad", "crappy", "terrible", "sucky", "up shit creek", "pathetic", "miserable", "badly", "terribly", "miserably"};
String input = "";
print("Hey there, how are you doing?");
scan(input);
for (int counter = 0; counter < goodwords.length; counter++){
if (input.contains(goodwords[counter])){
if (input.contains("not")){
sadanswer(badcomputerresponse);
}
else{
happyanswer(goodcomputerresponse);
}
}
}
for (int count2 = 0; count2 < badwords.length; count2++){
if (input.contains(badwords[count2])){
if (input.contains("not")){
happyanswer(goodcomputerresponse);
}
else{
sadanswer(badcomputerresponse);
}
}
}
}
public static void sadanswer(String[] badcomputerresponse){
int randomanswer = 0;
random(0, badcomputerresponse.length, randomanswer);
print(badcomputerresponse[randomanswer]);
}
public static void happyanswer(String[] goodcomputerresponse){
int randomanswer = 0;
random(0, goodcomputerresponse.length, randomanswer);
print(goodcomputerresponse[randomanswer]);
}
}
edit: thank you people who gave me help instead of downvoting me.
To the people who downvoted me, you stink!
First you define a bunch of scan methods like this:
public static void scan(String dumpinto){
Scanner x = new Scanner(System.in);
dumpinto = x.next();
}
Then you call it like this:
String input = "";
print("Hey there, how are you doing?");
scan(input);
That function does not do what it looks like it does. String dumpinto is an input parameter to the method. You can't write output to it. Once the method is done executing, the value that you typed in is lost. After you call scan(input);, the input variable still contains "". (Print it out or use a debugger to verify.)
Your scan method needs to return a value. Better yet, get rid of those methods altogether and just use one Scanner object to get input from the user.

I have an error with a math operation Java?

I created a code that is meant to accept a user-input then add 5 to it, this is the code. When I enter any number, It returns 0. EDIT: I moved the reCalculate down under main, nothing changes
package files;
import java.util.*;
public class CalculatorTest {
static Scanner userFirstNumber = new Scanner(System.in);
static int numberReCalculated;
public static int reCalculate(int a){
int numberReCalculated = a + 5;
return numberReCalculated;
}
public static void main(String[] args){
int bobson;
System.out.print("Enter a number, I will do the rest : ");
bobson = userFirstNumber.nextInt();
reCalculate(bobson);
System.out.println(numberReCalculated);
}
}
Your declaration of int numberReCalculated = a + 5; shadows the field declaration static int numberReCalculated;. Either change int numberReCalculated = a + 5; to numberReCalculated = a + 5;, or rewrite the entire code to be idiomatic and organized:
public class CalculatorTest {
static Scanner userFirstNumber = new Scanner(System.in);
public static int reCalculate(int a){
return a + 5;
}
public static void main(String[] args){
int input;
System.out.print("Enter a number, I will do the rest : ");
input = userFirstNumber.nextInt();
int result = reCalculate(bobson);
System.out.println(result);
}
}
I have no idea how "bobson" is a descriptive and self-documenting variable name.

Categories

Resources