Java 8 Streams IO - Tests - java

I've written a simple class whose reading and writing files by using a single stream.
Now I want to test it by using JUnit test or something like that but I have no clue where to start with this because as u can see this is only one stream and text is immediately printing to a new file.
public class OneStreamIOFile {
public void fileReaderWriter(String fileReadPath, String filePrintName) {
try (Stream<String> streamReader = Files.lines(Paths.get(fileReadPath));
PrintWriter printWriter = new PrintWriter(filePrintName)) {
streamReader
.filter(line -> line.matches("[\\d\\s]+"))
.map(line -> Arrays.stream(line.trim().split("[\\s]+"))
.reduce((a, b) -> a + "+" + b).get() + "="
+ Arrays.stream(line.trim().split("[\\s]+"))
.mapToInt(Integer::valueOf).sum())
.forEachOrdered(printWriter::println);
} catch (IOException e) {
System.out.println("File not found");
e.printStackTrace();
}
}
}
Main class
public class Main {
public static void main(String[] args) {
String filePath = "src/test/java/resources/1000.txt";
String filePrintName = "resultStream.txt";
new OneStreamIOFile().fileReaderWriter(filePath, filePrintName);
}
}
Any idea how to deal with this?

A unit test has to focus on the behavior, not on implementation details.
The way you are using to read from a stream and write to another stream doesn't matter.
Here you have to focus on what you have as input and as ouput of the method under test.
In input, you have String fileReadPath representing the file where you read from and and in output you have String filePrintName, the file created by the method under test.
So to unit test OneStreamIOFile.fileReaderWriter(), create an input test file and create an expected output test file containing what you expect as the input test file is passed to the method.
Of course store them in your test folders.
In your test, pass their String representation to the method under test.
Then, assert that the file created by the method has the same content as the expected output file.

You can check if the file has written by using below code snippet.
public class Sample {
#Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
#Test
public void testFileReaderWriter() throws IOException, InterruptedException {
File file=temporaryFolder.newFile("sample.txt");
Date createdTime=new Date();
OneStreamIOFile options=new OneStreamIOFile();
Thread.sleep(1000);
options.fileReaderWriter(file.getAbsolutePath(),"hellow");
Date modifiedTime=new Date();
Assert.assertTrue(createdTime.getTime()<modifiedTime.getTime());
}
}
You have to give some time after creating the file and if you need to check content you can read files content and assert it.
TemporyFolder is a rule using to handle file operations in Junit.

Related

Why won't my my catch block work?

I'm trying to test out the throws FileNotFoundException. At first, I placed my exec.txt in my project folder to test out my "testing" string & it works fine when I run my program.
But now, I removed my exec.txt file from my folder to see if the catch() part in the main method would work, but it doesn't. The File not found part of the catch() part won't appear in the console.
import java.io.*;
public class Crashable {
public static void openFile(String f) throws FileNotFoundException {
PrintWriter f1 = new PrintWriter(f);
f1.write("testing");
f1.close();
}
public static void main(String[] args) {
String f = "exec.txt";
try {
openFile(f);
} catch(FileNotFoundException e) {
System.out.println("File not found");
}
}
}
As stated in the documentation, an FileNotFoundException will be thrown when a file couldn't be accessed or created.
FileNotFoundException - If the given string does not denote an existing, writable regular file and a new regular file of that name cannot be created, or if some other error occurs while opening or creating the file
In your case it could create a new file, so no exceptions are thrown.
you can get it to throw the execption by trying creating the file in a non-existing dir:
String f = "zzz/exec.txt"
You never throw the exception in the openFile method. From the Java docs,
public PrintWriter(File file)
throws FileNotFoundException
Creates a new PrintWriter, without automatic line flushing, with the specified file. This convenience constructor creates the necessary
intermediate OutputStreamWriter, which will encode characters using
the default charset for this instance of the Java virtual machine.
Parameters:
file - The file to use as the destination of this writer. If the file exists then it will be truncated to zero size; otherwise, a new
file will be created. The output will be written to the file and is
buffered.
So if the file isn't there, you create a new file. So essentially, everything is working because although the file isn't there, when you create the PrintWriter object, it creates a new file, and doesn't throw the error.
You are actually creating a new file every time with this piece of code :
PrintWriter f1 = new PrintWriter(f);
f1.write("testing");
f1.close();
Instead try this :
public static void openFile(String f) throws FileNotFoundException {
File file = new File(f);
if(!file.exists())
{
throw new FileNotFoundException();
}
else
{
//do Something with the file
}}
Hope it helps..

Execute Jar file in IDE and get the output (String)? [duplicate]

This question already has answers here:
Execute .jar file from a Java program
(10 answers)
Closed 6 years ago.
Is it possible to execute a Jar file on my IDE (IntelliJ) to get the output string for my own purpose on the project that I have?
I know that we can make system calls, but in this case I want to add a Jar file on my project and execute it whenever I want it.
For example: I have a project on IntelliJ, one of my classes (on this project) needs to get the output by running the Jar file (which is on my project).
On my terminal, I would do something like java -jar <jar_file>.jar <file>.asm and this would output a result to my terminal.
And I want to get that output from this command on my Java Class.
Your Jar file returns an output string, so I assume, it's main-method could look like:
public static void main(String[] args) {
System.out.println("output string");
}
And now, if you want to use this "output string" string in your own class, you could do it like this:
public class YourClass {
...
public String getOutputStringFromJar() {
String s = ""; // or = null;
try {
Process p = Runtime.getRuntime().exec("java -jar full/path/to/your/Jar.jar full/path/to/fibonacci.asm");// just like you would do it on your terminal
p.waitFor();
InputStream is = p.getInputStream();
byte b[] = new byte[is.available()];
is.read(b, 0, b.length); // probably try b.length-1 or -2 to remove "new-line(s)"
s = new String(b);
} catch (Exception ex) {
ex.printStackTrace();
}
return s;
}
...
}
Now you have the method, that returns the output string, and you can use it however you want, and you know how to execute a Jar file from your project whenever you want
Your ask is not precise, but if i understand what you're doing, you run the Mars.jar with .asm file in param, and you got an output like in the this link with Fibonacci numbers
and now you want to get the Fibonacci numbers in your program? if that is what you need, i would suggest you to decompile the jar to understand his content
When you do so, you'll see that the main class in the jar is like this
public class Mars {
public static void main(String[] args) {
new mars.MarsLaunch(args);
}
}
so simply when you add the jar to your class path, you need to do somthing like this
public static void main(String[] args) throws FileNotFoundException {
// this will redirect your system output to a file named output.txt
PrintStream out = new PrintStream(new FileOutputStream("output.txt"));
System.setOut(out);
String [] myAsmFile = {"C:/produits/Fibonacci.asm"};
new mars.MarsLaunch(myAsmFile);
// and then you can read the output.txt file
}
hope this help you

Junit Test Java

Can someone please let me know how to write a Junit test for the if statement on the below method? Thanks
public String preGame() {
Scanner gameMode = new Scanner(System.in);
// Enforce player to select a valid game Option
while (!gameMode.hasNext("1") && !gameMode.hasNext("2") && !gameMode.hasNext("3")){
System.out.print(leftBorder + "Please enter a valid option (1,2,3)");
gameMode.next();
}
String gameOption = gameMode.next();
String optionMessage = null;
if (gameOption.equals("1")) {
optionMessage = "Human vs Human";
} else if (gameOption.equals("2")) {
optionMessage = "Human vs Computer";
} else if (gameOption.equals("3")) {
optionMessage = "Computer vs Computer";
}
System.out.println(leftBorder + "you've selected a game of " + optionMessage);
return gameOption;
}
While this is a bad design, as mentioned in comments above, the easiest way to test this code WITHOUT changing the source is to mock STDIN which is read by the Scanner in the method. The only part to remember is to change STDIN back after the test. This can be done with #Before and #After.
private InputStream realStdIn;
#Before
public void replaceStdIn(){
realStdIn = System.in;
}
#After
public void restoreStdIn(){
//after test put STDIN back as System.in
System.setIn(realStdIn);
}
Now our tests can set mock InputStream as our new STDIN
#Test
public void testGameMode1(){
InputStream in = new ByteArrayInputStream("1".getBytes());
System.setIn(in);
//now we can call preGame()
assertEquals("Human vs Human".equals(preGame());
}
In addition to dkatzel, if you want to test the output stream you can intercept that too. In stead of doing it in a #Before and #After you can also put the logic into a reusable JUnit Rule. Here's a rule I wrote that helps me test the System.out classes in this test.

Java, Junit - Capture the standard input / Output for use in a unit test [duplicate]

This question already has answers here:
JUnit test for System.out.println()
(14 answers)
Closed 8 years ago.
I'm writing integration tests using JUnit to automate the testing of a console based application. The application is homework but this part isn't the homework. I want to automate these tests to be more productive -- I don't want to have to go back and retest already tested parts of the application. (Standard reasons to use Unit tests)
Anyway, I can't figure out or find an article on capturing the output so that I can do assertEquals on it nor providing automated input. I don't care if the output/input goes to the console/output pane. I only need to have the test execute and verify the the output is what is expected given the input.
Anyone have an article or code to help out with this.
Use System.setOut() (and System.setErr()) to redirect the output to an arbitrary printstream - which can be one that you read from programmatically.
For example:
final ByteArrayOutputStream myOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(myOut));
// test stuff here...
final String standardOutput = myOut.toString();
The System class has methods setIn(), setOut() and setErr() that allow you to set the standard input, output and error streams, e.g. to a ByteArrayOutputStream that you can inspect at will.
Here is the solution in place of ByteArrayOutputStream. It does not add anything to the idea of System.setOut. Rather, I want to share the implementation that is better than capturing everything into ByteArrayOutputStream. I prefer to capture only selected information and let all log messages to appear in the console as they are logged rather than capturing everything into a balckbox (of which size?) for later processing.
/**
* Once started, std output is redirected to this thread.
* Thread redirects all data to the former system.out and
* captures some strings.*/
static abstract class OutputCaputre extends Thread {
// overrdie these methods for System.err
PrintStream getDownstream() { return System.out;}
void restoreDownstream() { System.setOut(downstream);}
// will be called for every line in the log
protected abstract void userFilter(String line);
final PrintStream downstream;
public final PipedInputStream pis;
private final PipedOutputStream pos;
OutputCaputre() throws IOException {
downstream = getDownstream();
pos = new PipedOutputStream();
pis = new PipedInputStream(pos);
System.setOut(new PrintStream(pos));
start();
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(pis));
// once output is resotred, we must terminate
while (true) {
String line = br.readLine();
if (line == null) {
return;
}
downstream.println(line);
userFilter(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void terminate() throws InterruptedException, IOException {
restoreDownstream(); // switch back to std
pos.close(); // there will be no more data - signal that
join(); // and wait until capture completes
}
};
Here is an example of using the class:
OutputCaputre outputCapture = new OutputCaputre() {
protected void userFilter(String line) {
downstream.println("Capture: " + line);
}
};
System.out.println("do you see me captured?");
// here is your test
outputCapture.terminate(); // finally, stop capturing

how to clear file before putting data there?

I need to save some data into text file. I'm using class Files with its method write().
If such file doesn't exist - everything alright. The problem is if such file already exists it appends new data to the end of the file. And I need to clear it first. The code is:
public static void main(String[] args) {
DepoList test0 = new DepoList();
test0.init();
ArrayList<Depo> list0 = test0.getList();
Collections.sort(list0);
for (Depo depo : list0) {
String str = String.format("sum = %1$8.2f interest = %2$7.2f\n", depo.getSum(), depo.getIncome());
System.out.format(str);
try {
Files.write(Paths.get("depo.txt"), str.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println();
I think I need to add some another StandardOpenOperation. How to clear the file before putting data there?
Remove StandardOpenOption.CREATE,Standardoption.APPEND this just appends your new data to the existing one
Use Files.write((Paths.get("depo.txt"), str.getBytes());

Categories

Resources