JUnit force BufferedReader to throw IOException - java

I have following method
public static String readPostParams(Request request, String param) {
BufferedReader br = new BufferedReader(new InputStreamReader(request.getBodyAsStream()));
String line;
try {
while ((line = br.readLine()) != null) {
if (line.contains(param)) {
//System.out.println("---> " + param + " :" + getValue(line));
return getValue(line);
}
}
} catch (IOException ex) {
// Ignore
}
return "";
}
I want a JUnit Unit test to force BufferedReader to throw IOException so I can cover that part also.

You should get an IOException if the file is "in use" So you can try this:
(I have never tested this)
In you test use
final RandomAccessFile lockFile = new RandomAccessFile(fileName, "rw");
lockFile.getChannel().lock();
Then call your method from above and unlock the file once you are done.

If you want to test this method for IOException, you should propagate the exception to the calling method by removing the try catch block and adding the throws clause to your method:
public static String readPostParams(Request request, String param) throws IOException;
There is an attribute called as 'expected' for the #Test annotation which you can use to check for exceptions. Your test case which checks for IOexception from your method will look somewhat like this:
#Test(expected=IOException.class)
public void shouldReadPostParamsThrowIOExceptionIfInvalidRead(){
}

Related

Throw Exception in method who throws this Excpetion

I am doing a method who return an UUID of a Minecraft player from his username using the Mojang API. This method takes a String in parameter (the username of the player who we want to know the UUID). To use the resultat of the API, I use the SimpleJSON library (to parse the JSON result into a String to return).
My method throws 2 checked exceptions : the IOExeption and the Parseexception, cause I want.
When a wrong username (so an username who doesn't exist) the API return a empty JSON object and my method throws an IOException in this case. And this is my problem, when a wrong username is in paramter of the method, the method throw a new IOExcpetion but with a try and catch for the method, the throwing exception isn't catched.
My method :
public static String getUUID(String name) throws IOException, ParseException {
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + name);
URLConnection uc = url.openConnection();
BufferedReader bf = new BufferedReader(new InputStreamReader(uc.getInputStream()));
StringBuilder response = new StringBuilder();
String inputLine;
while ((inputLine = bf.readLine()) != null) {
response.append(inputLine);
}
bf.close();
if (response.toString().isEmpty()) {
throw new IOException();
}
JSONParser parser = new JSONParser();
Object object = parser.parse(response.toString());
JSONObject jo = (JSONObject) object;
String str = (String) jo.get("id");
return str.replaceAll("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5");
}
An example of using a valid username :
public static void main(String[] args) {
try {
System.out.println(getUUID("Jeb_"));
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
And now an example with a wrong username:
public static void main(String[] args) {
try {
System.out.println(getUUID("d"));
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
Thank you.
Have you verified that your exception might get caught? If it is caught, the code prints a stack trace. But if it is not caught, the JVM will print a stack trace anyway.
So throw the exception with some message you can verify, like
throw new IOException("Invalid user");
and catch the exception by being a bit more verbose:
catch (IOException | ParseException e) {
System.out.println("Could not lookup user "+username+", caught "+e.getClass().getName()+": "+e.getMessage());
}
Actually, your exception is caught, you can check it as follows:
public static void main(String[] args) {
var username = "d";
try {
System.out.println(getUUID(username));
} catch (IOException | ParseException e) {
System.out.println("User " + username + " not found!");
e.printStackTrace();
}
}
The output of the program will be:
User d not found!
java.io.IOException
at com.company.Main.getUUID(Main.java:37)
at com.company.Main.main(Main.java:17)
This output means that code inside catch block was executed.

read from txt and add to treeset

I need to read a txt file and store my data to a treeSet.
public class UrbanPopulationStatistics {
private Set<UrbanPopulation> popSet;
private File file;
private BufferedReader br;
public UrbanPopulationStatistics(String fileName) throws IOException {
this.popSet = new TreeSet<>();
readFile("population.txt");
}
private void readFile(String fileName) throws IOException {
try {
br = new BufferedReader(new FileReader(fileName));
String line;
while ((line=br.readLine()) != null) {
String[] array = line.split("/");
popSet.add(new UrbanPopulation(array[0], Integer.parseInt(array[1]), Integer.parseInt(array[4])));
}
} catch (IOException e) {
e.printStackTrace();
}
br.close();
}
#Override
public String toString() {
String s = popSet.toString().replaceAll(", ", "");
return "UrbanPopulationStatistics:\n" + s.substring(1, s.length() - 1) + "\n";
}
public static void main(String[] args) throws IOException {
UrbanPopulationStatistics stats = new UrbanPopulationStatistics("population.txt");
System.out.println(stats);
}
}
I have tried to turn what the buffered reader reads into an array and then add it into my treeSet, but I get the error: Exception in thread "main" java.lang.UnsupportedOperationException: Not supported yet.
You have an extra period after parseInt at Integer.parseInt.(array[4])));.
Be careful when writing code. Syntax errors don't show up "nicely", i.e. the error message is not very helpful in most cases. It does show you the approximate location of the error though.
The problem with your code is you are not storing what you read from the buffer (and hence reading twice from the buffer). You need to assign what you read in a variable to check for null as below:
private void readFile(String fileName) throws IOException {
try {
br = new BufferedReader(new FileReader(fileName));
String line = null;
while ((line = br.readLine()) != null) {
String[] array = line.split("/");
popSet.add(new UrbanPopulation(array[0], Integer.parseInt(array[1]), Integer.parseInt(array[4])));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
br.close();
}
}
Also I would close the BufferedReader in the finally block to avoid resource leaks.
I tried to reproduce the error using your code, but it doesn't happened. Your code is ok.
UnsupportedOperationException are exceptions that can happen when you try to add an element in a collection.
But TreeSet implements the add method.

Try and catch blocks: whether in the class itself or when I call the method outside the class

Could you help me understand where should I throw exceptions and catch them.
Please, have a look at my code. I thought that in Thrd class I have already thrown and caught the exception. But when I wrote in the main class FirstThread.readFile("ParallelProgramming.txt");, I faced a runtime error - unhandled exception. So, I had to use try and catch. So, I somehow can't understand why in the Thd class my try and catch blocks didn't work.
package parallelprogramming;
import java.lang.Thread;
import java.io.*;
public class Thrd extends Thread {
public void readFile(String File) throws FileNotFoundException {
FileReader fr = new FileReader(File);
BufferedReader br = new BufferedReader(fr);
String s;
try {
while ((s = br.readLine()) != null) {
System.out.println(s);
}
fr.close();
}
catch (FileNotFoundException FNFD) {
System.out.println("File not found!");
}
catch (IOException IOE){
System.out.println("IOException caught!");
}
}
}
package parallelprogramming;
import java.io.FileNotFoundException;
public class ParallelProgramming {
public static void main(String[] args) throws FileNotFoundException {
Thrd FirstThread = new Thrd();
try {
FirstThread.readFile("ParallelProgramming.txt");
} catch (FileNotFoundException FNFD) {
System.out.println("File not found!");
}
}
}
The rules with checked exceptions (and this includes IOException, which FileNotFoundException is a child of), are as follows:
if you cannot, or do not want, to handle it in your current method, declare that the method throws it;
if you want to handle it in your current method, then catch it; note that even in this case you can rethrow that exception;
if main() throws any exception, and this exception triggers, the program terminates.
Now, we suppose that you are using Java 7. In this case, do that:
public void readFile(final String file)
throws IOException
{
final Path path = Paths.get(file);
for (final String line: Files.readAllLines(path, StandardCharsets.UTF_8))
System.out.println(line);
}
Why bother? ;)
If you don't want to do that but read line by line, then:
public void readFile(final String file)
throws IOException
{
final Path path = Paths.get(file);
try (
final BufferedReader reader = Files.newBufferedReader(path,
StandardCharsets.UTF_8);
) {
String line;
while ((line = reader.readLine()) != null)
System.out.println(line);
}
}
The second form is preferred if you wish to treat exceptions specifically. Note that with Java 7, you have meaningful exceptions as to why you cannot access the file vs IOException: NoSuchFileException, AccessDeniedException, etc etc. All these inherit FileSystemException. The old file API can't do that for you.
This means that if you want to deal with filesystem level errors you can do:
catch (FileSystemException e) { /* ... */ }
where before that you did:
catch (FileNotFoundException e) { /* ... */ }
Translated to the code above, if you want to catch exceptions you'll then do:
// All exceptions handled within the method -- except if you rethrow it
public void readFile(final String file)
{
final Path path = Paths.get(file);
try (
final BufferedReader reader = Files.newBufferedReader(path,
StandardCharsets.UTF_8);
) {
String line;
while ((line = reader.readLine()) != null)
System.out.println(line);
} catch (FileSystemException e) {
// deal with a filesystem-level error
// Note that you MUSt catch it before IOException
// since FileSystemException inherits IOException
} catch (IOException e) {
// deal with a low-level I/O error
}
}
Remove 'throws FileNotFoundException' from the readFile method of class Thrd then you dont need to handle this exception in main method of class ParallelProgramming.
As you throw FileNotFoundException from readFile method then exception will pass to the method will called this i.e. then main method need to handle this exception.
There are two ways to handle an exception either you need to catch it or throw it again.
In the readFile method you have done both. you caught the exceptions using catch blocks then you have mentioned that readFile method throws FileNotFoundException, so when ever you use readFile method you need to catch the exception again.

Resolving IOException, FileNotFoundException when using FileReader

I've not been able to resolve the following exception in the code below. What is the problem with the way I use BufferedReader? I'm using BufferedReader inside the main method
OUTPUT :-
ParseFileName.java:56: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
BufferedReader buffread = new BufferedReader (new FileReader("file.txt"));
// ParseFileName is used to get the file name from a file path
// For eg: get - crc.v from "$ROOT/rtl/..path/crc.v"
import java.util.regex.Pattern;
import java.io.*;
public class ParseFileName {
//Split along /'s , and collect the last term.
public String getName (String longName) {
String splitAt = "/";
Pattern pattern1 = Pattern.compile(splitAt);
String[] parts = pattern1.split(longName);
System.out.println("\nparts.length = " + parts.length);
//Return the last element in the array of strings
return parts[parts.length -1];
}
public static void main(String[] args) {
ParseFileName superParse = new ParseFileName();
BufferedReader buffread = new BufferedReader (new FileReader("file.txt"));
String line;
while ((line = buffread.readLine())!= null) {
String fileName = superParse.getName(line);
System.out.println("\n" + line + " => " + fileName);
}
buffread.close();
}
}
UPDATE :
The following works:
public static void main(String[] args) throws FileNotFoundException, IOException {
However try.. catch still has some nagging issues for me:
try {
BufferedReader buffread = new BufferedReader (new FileReader("file.txt"));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex2) {
ex2.printStackTrace();
}
buffread dosent seem to get the file name. I get this error:
javac ParseFileName.java ParseFileName.java:67: cannot resolve symbol
symbol : variable buffread
location: class ParseFileName
while ((line = buffread.readLine())!= null) {
Add throws FileNotFoundException, IOException in the header of your method. It looks like just throwing the IOException will solve your problem, but incorporating both will allow you to tell if there was a problem with the file's existence or if something else went wrong (see catch statements below).
i.e.
public static void main(String[] args) throws FileNotFoundException, IOException {
Alternately, if you'd like to catch a specific exception and do something with it:
try {
BufferedReader buffread = new BufferedReader (new FileReader("file.txt"));
} catch (FileNotFoundException ex) {
// Do something with 'ex'
} catch (IOException ex2) {
// Do something with 'ex2'
}
Update to resolve the updated issue: This is just a simple scope problem which can be solved by declaring the BufferedReader outside of the try statement.
BufferedReader buffread = null;
try {
buffread = new BufferedReader (new FileReader("file.txt"));
} catch (FileNotFoundException ex) {
...
You have to add throws statement into the signature of method main or wrap code in
try {
...
} catch (FileNotFoundException e) {
...
}
Your code can throw FileNotFoundException or IOException which is Checked Exception. You need to surround your code in a try-catch block or add a throws declaration in your main function.
The BufferReader can throw an exception if the file cannot be found or opened correctly.
This error message is telling you that you need to handle this exception. You can wrap the line where you create the BufferReader in a try/catch block. This will handle the case an IOException is thrown and print out the stack trace.
public static void main(String[] args) {
ParseFileName superParse = new ParseFileName();
BufferedReader buffread;
try
{
buffread= new BufferedReader (new FileReader("file.txt"));
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
String line;
while ((line = buffread.readLine())!= null) {
String fileName = superParse.getName(line);
System.out.println("\n" + line + " => " + fileName);
}
buffread.close();
}
Another option is to add "throws IOException" to your method header.
public static void main(String[] args) throws IOException {
//...
}
This tells the compiler and callers of your method that you are choosing to not handle this exception and there is a chance it will be thrown.

Can I miss the catch clause to throw exception to its caller?

What kind of problem may occur for this code?
I think even exception occurs, this code can throw the exception to its caller.
So it does NOT generate any trouble.
How can I improve it?
public static void cat(File named) {
RandomAccessFile input = null;
String line = null;
try {
input = new RandomAccessFile(named, “r”);
while ((line = input.readLine()) != null {
System.out.println(line);
}
return;
} finally {
if (input != null) {
input.close();
}
}
}
The code has to throw the IOException - try editing your code with eclipse and you would also get a suggestion to throw the Exception.
Also Java 1.7 has the new concept of "try-with-resources" - see the try statement below.
The resource used in try (...) is closed automatically.
public static void cat(File named) throws IOException
{
try (RandomAccessFile input = new RandomAccessFile(named, "r"))
{
String line = null;
while ((line = input.readLine()) != null)
{
System.out.println(line);
}
}
}
What kind of problem may occur for this code?
public RandomAccessFile throws FileNotFoundException.
public final String readLine() throws IOException.
public void close() throws IOException.
Since public class FileNotFoundException
extends IOException
You can change your method to:
public static void cat(File named) throws IOException
And now you don't need a try-catch blocks.
And the caller should catch the exception thrown by the method.
But why don't you want to catch the exceptions?
add the throws declaration in your method , and then caller of this method should have try catch block for this exception .
public static void cat(File named) throws IOException {
RandomAccessFile input = null;
String line = null;
try {
input = new RandomAccessFile(named, "r");
while ((line = input.readLine()) != null ){
System.out.println(line);
}
return;
} finally {
if (input != null) {
input.close();
}
}
}
//caller
try{
Class.cat(new File("abc.txt"));
}catch(IOException e)
{
//
}

Categories