I'm trying to test my main method (which should accept exactly one argument) for no arguments passed. Can't seem to understand what am I missing here to achieve that.The nature of my program is such that it reads input from a file, creates objects by passing parameters read from the file, and displays output.
Failure Message:
org.junit.ComparisonFailure: Expected :Please pass one argument
Actual :
Here's my Unit Test:
#Test
public void givenNoParameter_shouldAskForOne() throws IOException {
String[] args = {};
String output;
try (ByteArrayOutputStream bOutput = new ByteArrayOutputStream()) {
System.setOut(new PrintStream(bOutput));
Main.main(args);
bOutput.flush();
output = bOutput.toString();
}
String newLine = System.getProperty("line.separator");
String[] breakDownOutput = output.split(newLine);
assertEquals(1, breakDownOutput.length);
assertEquals("Please pass one argument", breakDownOutput[0]);
}
Main Method:
public static void main(String[] args) {
if(args.length == 1) {
DisplayOrder.setFilePath(args[0]);
DisplayOrder.display();
} else{
System.err.println("Please pass one argument");
}
}
I've realized I was using System.err.println() in my main. Changing that to System.out.println() fixed it.
Not showing your main method, my only guess is, that you do not write anything to "System.out" in your main, especially there is no System.out.println("Please pass one argument"); statement which is executed.
So, your unit test fails perfectly for a not expected value in "breakDownOutput[0]".
What you have to do is to make certain that the System.out.println("Please pass one argument"); is executed if no arguments were provided to your main.
Also check your class name Main.main(...) since there might be other Main classes imported which will never print out your expected values to System.out
Related
Keep getting error of "Call the program with exactly one argument!", but am unsure where I need to make changes to run the program correctly. Thanks!!
class Main {
private static ArrayList<ArrayList<int[]>> list;
public static void main(String[] args) throws IOException {
if (args.length != 3) {
System.out.println("Call the program with exactly one argument!");
System.out.println("argument 1: path to map file");
System.out.println("argument 2: path to airports file");
System.out.println("argument 3: path to flights file");
System.exit(-1);
}
You have to call your main method with three parameters as you point in your code (args.length). In order to call your method via command line:
- java Main.java param1 param2 param3
If you want to call main method using only one parameter, then you'll get println messages you write.
So I always use Eclipse to run my java stuff, I have no clue how to use command prompts. I have an assessment that will be graded by a bot where 2 string parameters will get passed into a function which returns a boolean value.
The bot is going to use a command like "java main.java xyz zyx" to open the file
(assuming xyz and zyx are the strings).
So my question is, to catch those 2 strings, do I have to use 2 variables to catch the 2 string. For example:
string1 = Scanner.nextln(); // This will catch "xyz" into string1??
string2 = Scanner.nextln(); // This will catch "zyx"??
Or does string 1 catch both "xyz zyx" and I have to use a loop to separate them into 2 strings? Thanks in advance :)
Your Main method can be used to catch arguments passed from command line.
public static void main(String[] args) {
System.out.println(args);
}
public static void main(String[] args) {
...
}
Is your program written like this? As in the signature of the main function. The signature holds them as strings in an array. Then you have to process those strings.
This question already has answers here:
JUnit test for System.out.println()
(14 answers)
Closed 4 years ago.
I want to test method setDay() using arguments [-1,0,24,2,32].
I know that Scanner reader can be
String test="-1 0 24 2 32";
Scanner reader=new Scanner(test);
The main problem is infinite loop and void method. How can we test this kind of code? Here is example code:
public NameOfTheDay(){
int day=1;
}
{...}
public void setDay(Scanner reader) {
while (true) {
System.out.print("Day: ");
String input = reader.nextLine();
if (input.matches("\\d{2}")) {
int day = Integer.parseInt(input);
if (day > 0 && day < 32) {
this.day = day;
return;
}
}
System.out.println("Wrong day. Try again.");
}
}
Thanks for the answer.
How can we test this kind of code?
You cannot.
unittest verify the public observable behavior of your code under test where "public observable behavior" is any rreturn value or communication with dependencies.
Communication with dependencies is checked with test doubles which we (usually) create using a mocking framework and which we inject into the code under test.
A major prerequest is that you code cleanly incorporates Single Responsibility/Separation of Concerns pattern.
Your code does not return anything and has no possibility to replace the dependencies of interest (here System.out) because it mixes business logic with user interaction.
Some may argue, that you can assign a test double to System.out or use PowerMock to replace dependencies but IMHO this is just a surrender to your bad design and will not pay off as your program grows.
I will not focus on the contents of your method, but just on the question on how to unit test a method expecting a Scanner object as parameter.
The easy answer is: Provide your test input data as a String, and build a scanner around it, like this:
#Test
public void testSetDay_positive() {
String testInput = "23\n";
Scanner testScanner = new Scanner(testInput);
NameOfTheDay notd = new NameOfTheDay();
notd.setDay(testScanner);
Assert.assertEquals(23, notd.getDay()); // or whatever condition to test
}
Now it gets harder. Perhaps you want to test an invalid input first, and make sure the second input is used then?
#Test
public void testSetDay_negative_then_positive() {
String testInput = "999\n23\n"; // two lines of input here
Scanner testScanner = new Scanner(testInput);
NameOfTheDay notd = new NameOfTheDay();
notd.setDay(testScanner);
Assert.assertEquals(23, notd.getDay()); // or whatever condition to test
}
If you want to test if the error message is written to System.out, you would have to replace that with a custom stream to test afterwards:
ByteArrayOutputStream mockOut = new ByteArrayOutputStream();
PrintStream newOut = new PrintStream(mockOut);
System.setOut(newOut);
// execute test from above
Assert.assertTrue(new String(mockOut.toByteArray(), "UTF-8").contains("Wrong day. Try again."));
Still, most comments to your question contain valuable input (move validation to an extra method etc.) which should be considered.
I have pw_check.java and I need to run it with an argument first and then run it without argument in terminal.
java pw_check -g
java pw_check
But in second command, without argument, the system is throwing exception. How could I handle it to feed my requirement.
Check the code pw_check.java.
Probably there is something like
public static void main(String[] args) {
// Code accessing args[0]
}
This will cause an error if you don't have a parameter.
Modify with a code similar to the following:
public static void main(String[] args) {
String arg = DEFAULT_ARG;
if (args.length == 1) {
arg = args[0];
}
... // Code using arg DEFAULT or passed value
}
I am looking to do some error checking for my command line arguments
public static void main(String[] args)
{
if(args[0] == null)
{
System.out.println("Proper Usage is: java program filename");
System.exit(0);
}
}
However, this returns an array out of bounds exception, which makes sense. I am just looking for the proper usage.
The arguments can never be null. They just won't exist.
In other words, what you need to do is check the length of your arguments.
public static void main(String[] args) {
// Check how many arguments were passed in
if (args.length == 0) {
System.out.println("Proper Usage is: java program filename");
System.exit(0);
}
}
#jjnguy's answer is correct in most circumstances. You won't ever see a null String in the argument array (or a null array) if main is called by running the application is run from the command line in the normal way.
However, if some other part of the application calls a main method, it is conceivable that it might pass a null argument or null argument array.
However(2), this is clearly a highly unusual use-case, and it is an egregious violation of the implied contract for a main entry-point method. Therefore, I don't think you should bother checking for null argument values in main. In the unlikely event that they do occur, it is acceptable for the calling code to get a NullPointerException. After all, it is a bug in the caller to violate the contract.
To expand upon this point:
It is possible that the args variable itself will be null, but not via normal execution. Normal execution will use java.exe as the entry point from the command line. However, I have seen some programs that use compiled C++ code with JNI to use the jvm.dll, bypassing the java.exe entirely. In this case, it is possible to pass NULL to the main method, in which case args will be null.
I recommend always checking if ((args == null) || (args.length == 0)), or if ((args != null) && (args.length > 0)) depending on your need.
You should check for (args == null || args.length == 0). Although the null check isn't really needed, it is a good practice.
if i want to check if any speicfic position of command line arguement is passed or not then how to check?
like for example
in some scenarios 2 command line args will be passed and in some only one will be passed then how do it check wheather the specfic commnad line is passed or not?
public class check {
public static void main(String[] args) {
if(args[0].length()!=0)
{
System.out.println("entered first if");
}
if(args[0].length()!=0 && args[1].length()!=0)
{
System.out.println("entered second if");
}
}
}
So in the above code if args[1] is not passed then i get java.lang.ArrayIndexOutOfBoundsException:
so how do i tackle this where i can check if second arguement is passed or not and if passed then enter it.
need assistance asap.
If you don't pass any argument then even in that case args gets initialized but without any item/element.
Try the following one, you will get the same effect:
public static void main(String[] args) throws InterruptedException {
String [] dummy= new String [] {};
if(dummy[0] == null)
{
System.out.println("Proper Usage is: java program filename");
System.exit(0);
}
}