I am trying to test exception handling when using Opencsv's CSVReader. The data will be coming from a String.
It's not working because I am (probably) not properly mocking the CSVReader, but cannot quite figure out what I need to do.
Here's the class
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvValidationException;
// other imports skipped
public class MyCsvReader {
private Path contentsAsString;
private CSVReader csvReader;
public MyCsvReader(final String contentsAsString) {
InputStream inputStream = new ByteArrayInputStream(contentsAsString.getBytes());
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
csvReader = new CSVReaderBuilder(inputStreamReader)
.withSkipLines(0)
.withKeepCarriageReturn(false)
.build();
}
public void readData() {
String[] line;
try {
while ((line = csvReader.readNext()) != null) {
System.out.println("line:" + Arrays.toString(line));
}
} catch (IOException e) {
System.out.println("got IOException");
// I will be throwing a custom exception here
throw new RuntimeException(e);
} catch (CsvValidationException e) {
System.out.println("got CsvValidationException");
// and a different custom exception here
throw new RuntimeException(e);
}
}
}
and the test
public class MyCsvReaderTest {
#Test
public void testException() throws Exception {
String[] rows = {
"column1,column2,column3",
"test,abc,def"
};
String rowData = String.join("\n", rows);
CSVReader mock = Mockito.mock(CSVReader.class);
Mockito.when(mock.readNext()).thenThrow(new IOException("test"));
MyCsvReader reader = new MyCsvReader(rowData);
try {
reader.readData();
fail("Expected an exception, but call succeeded");
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
When I run it, reader.readNext() does not throw an exception
line: [column1, column2, column3]
line: [test, abc, def]
org.opentest4j.AssertionFailedError: Expected and exception, but call succeeded
... stack trace deleted
Suggestions on what I need to do? Thanks!
You don't use a mocked instance but a real one.
If the goal here is throw an exception when mock.readNext() happens you have to do something like this in order to inject your mocked instance of CSVReader:
public class MyCsvReader {
private final CSVReader csvReader;
public MyCsvReader(final CSVReader csvReader) {
this.csvReader = csvReader;
}
public MyCsvReader(final String contentsAsString) {
this(getCsvReader(contentsAsString));
}
private static CSVReader getCsvReader(final String contentsAsString) {
InputStream inputStream = new ByteArrayInputStream(contentsAsString.getBytes());
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
return new CSVReaderBuilder(inputStreamReader)
.withSkipLines(0)
.withKeepCarriageReturn(false)
.build();
}
public void readData() {
String[] line;
try {
while ((line = csvReader.readNext()) != null) {
System.out.println("line:" + Arrays.toString(line));
}
} catch (IOException e) {
System.out.println("got IOException");
// I will be throwing a custom exception here
throw new RuntimeException(e);
} catch (CsvValidationException e) {
System.out.println("got CsvValidationException");
// and a different custom exception here
throw new RuntimeException(e);
}
}
}
public class MyCsvReaderTest {
#Test
public void testException() throws Exception {
CSVReader mock = Mockito.mock(CSVReader.class);
Mockito.when(mock.readNext()).thenThrow(new IOException("test"));
MyCsvReader reader = new MyCsvReader(mock);
try {
reader.readData();
fail("Expected an exception, but call succeeded");
} catch (RuntimeException ignored) {
}
}
}
Related
I have this bit of code which depends from a custom Exception thrown by a function inside findID() it throws a NoClientFound Exception that I made whenever this mentioned function returns a null (The client does not exist).
The IDE suggests that I shall apply that Exception into the code, but in this bit of code, where I need the ID to be null (unique IDs) I "can't catch that exception" since if I catch it, the function will not be executed as intended.
Question: How I can manage this?
Function with the Exception problem
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
if (findID(c.getID()) == null) {
try (BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));) {
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
} catch (IOException e) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE,
null, "Error appeding data to file" + e);
}
}
} catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
} finally {
}
return addded;
}
Exception Code
public class NoClientFound extends Exception {
private String msg;
public NoClientFound() {
super();
}
public NoClientFound(String msg) {
super(msg);
this.msg = msg;
}
#Override
public String toString() {
return msg;
}
You can catch that exception and handle it accordingly. When you catch NoClientFound exception that means findID(c.getID()) is null. So without handling that in the if block you can handle that within the catch block.
public boolean add(Client c) {
StringBuilder sb = new StringBuilder();
boolean added = false;
try {
// call the function
findID(c.getID());
} catch (NoClientFound ex) {
//handle the NoClientFound exception as you like here
BufferedWriter bw = new BufferedWriter(
new FileWriter(fitxer, true));
//Add client to file
bw.write(sb.append(c.getID()).append(SEPARADOR).
append(c.getName()).toString());
bw.newLine();//New line
bw.flush(); //Push to file
added = true;
}catch (IOException ex) {
Logger.getLogger(DaoClient.class.getName()).log(Level.SEVERE, null,
"Error appeding data to file" + ex);
}finally {
}
return addded;
}
I assume you already have a null check on findID(...)
if( c == null || findID(c.getID()) == null){
throw new NoClientFound("Client not found!");
}else{
//add your file writing operation
}
and Also in NoClientFound class extend it from RuntimeException, not the Exception.
public class NoClientFound extends RuntimeException {
...
}
Caller method:
public void caller(){
Client client = new Client();
client.setId(1);
...
try{
add(client);
}catch(NoClientFound ex){
//client not found then create one for ex...
}
catch(Exception ex){
//somthing else happend
log.error(ex.getmessge());
}
}
I define a custom exception like so :
package source.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ValidationException extends Exception
{
private static final Logger logger = LoggerFactory.getLogger("source.exception.ValidationException");
public ValidationException(String message)
{
super(message);
ValidationException e = new ValidationException();
logger.error("Exception : {}" , e);
}
}
In the main program I use this exception like so :
public void readFile(String path) throws ValidationException
{
logger.debug("Input file path = {}" , path);
try
{
if(validatePath(path))
{
mathExpressionReader = new BufferedReader(new FileReader(path));
}
else
{
throw new ValidationException("Your file dose not exist!");
}
}
catch(Exception ex)
{
logger.error("Exception {} has occurred" , ex);
}
}
Now I don't know how to print stack trace when validatePath fail(means if statement become false) .Can anyone help me to print stack trace in custom exception?
Why not just using e.printStackTrace()?
public class ValidationException extends Exception
{
public ValidationException(String message)
{
super(message);
}
}
public void readFile(String path) throws ValidationException
{
logger.debug("Input file path = {}" , path);
try
{
if(validatePath(path))
{
mathExpressionReader = new BufferedReader(new FileReader(path));
}
else
{
throw new ValidationException("Your file dose not exist!");
}
} catch (ValidationException e) {
// This will print the stack trace.
e.printStackTrace();
}
}
import java.io.*;
public class Test13
{
public static void main(String[] args) throws IOException
{
FileInputStream fis1 = new FileInputStream("D:/abc.txt");
FileInputStream fis2 = new FileInputStream("D:/xyz.txt");
SequenceInputStream sis = new SequenceInputStream(fis1,fis2);
int i;
while((i = sis.read())!=-1)
{
System.out.println((char)i);
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
I think you tried something like that. I inserted some explenations to the Exception-Handling
import java.io.FileInputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
public class Test13 {
//because all exceptions are already catched main will never throw one
public static void main(String[] args) throws IOException {
try {
//if an exception raises anywhere from here ...
FileInputStream fis1 = new FileInputStream("D:/abc.txt");
FileInputStream fis2 = new FileInputStream("D:/xyz.txt");
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
int i;
while ((i = sis.read()) != -1) {
System.out.println((char) i);
}
//... to here ...
} catch (Exception ex) {
//this catch block code will be executed
ex.printStackTrace();
}
}
}
You should have
try{
//function which throws exceptions
}
catch( SpecificException e ) {
// if a specific exception was thrown, handle it here
}
catch(Exception ex) {
// if a more general exception was thrown, handle it here
}
finally{
}
Below is the updated code and its working fine.
import java.io.*;
public class Test13
{
public static void main(String[] args) throws IOException {
try {
FileInputStream fis1 = new FileInputStream("D:/abc.txt");
FileInputStream fis2 = new FileInputStream("D:/xyz.txt");
SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
int i;
while ((i = sis.read()) != -1)
{
System.out.println((char) i);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
I wrote the following class for an iterator that iterates along the lines of a file.
import java.io.*;
import java.util.Iterator;
public class FileIterator implements Iterator<String> {
private BufferedReader reader;
public FileIterator(String filename) {
this.reader = getBufferedReader(filename);
}
private static BufferedReader getBufferedReader(String filename) {
File file = new File(filename);
if(file.exists()) {
try {
return new BufferedReader(new InputStreamReader(
new FileInputStream(new File(filename)),"UTF-8"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
} else {
System.out.println(filename + " is not there");
return null;
}
}
public boolean hasNext() {
try {
return reader.ready();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public String next() {
try {
return reader.readLine();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public void remove() {}
}
Now my question is a bit naive. Will be the reader closed once the iterator is no more used, when the GC will take care of it? Would the class improve if I close the reader manually? Maybe as a side effect in the hasNext() method:
public boolean hasNext() {
try {
if(reader.ready()) return true;
else {
reader.close();
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
Thanks!
If you really want to do this, I would have FileIterator implement Closeable and delegate the call to the underlying BufferedReader. You could even use it in a Java 7 try-with-resources block.
date time kg
12/10/2013 00.00.01 1
13/11/2013 00.00.05 2
17/12/2013 00.00.90 5
21/12/2013 00.00.23 6
27/12/2013 00.00.43 9
I have these data in an txt file. I would like to make o program in java that would read these data. I ' ve written the code above but I have mistakes. Could someone help me? The data have space between each other.
import java.io*;
public class ReadTextfile{
public static void main (String[] args) {
File file = new File ("test.txt");
StringBuilder line = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader (new FileReader(file));
String text = null;
while ((text = reader.readLine()) !=null) {
line.append(text)
.append(System.getProperty ("line.separator"));
}
}
catch (IOException e) {
e.printStackTrace();
catch (FileNotFoundException e) {
e.printStackTrace();
}finally {
try {
if (reader !=null){
reader.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(line.toString());
}
}
boy you are only having some syntax problem
1 : replace
import java.io* with import java.io.*
2 : take care of your catch body being started and closed properly
try
{
// your code
}
catch(Exception e)
{
}
here is the working code , compare your program
import java.io.*;
public class ReadTextfile{
public static void main (String[] args)
{
File file = new File ("C:/Users/hussain.a/Desktop/test.txt");
StringBuilder line = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader (new FileReader(file));
String text = null;
while ((text = reader.readLine()) !=null) {
line.append(text)
.append(System.getProperty ("line.separator"));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
if (reader !=null){
reader.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
System.out.println(line.toString());
}
}
catch (FileNotFoundException e)
This is unreachable code, since above it you caught IOException.
Note that:
public class FileNotFoundException extends IOException
Your code won't compile. Remove this catch (You didn't even close it..)
Another thing, if this is not a type, you should replace java.io* with import java.io.*.
I would take the following approach:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ReadTextFile
{
public static void main(String[] args) throws FileNotFoundException
{
File file = new File("test.txt");
Scanner scanner = new Scanner(file);
List<Result> results = new ArrayList<Result>();
while(scanner.hasNextLine())
{
String currentLine = scanner.nextLine();
String [] resultArray = currentLine.split(" ");
results.add(new Result(resultArray[0], resultArray[1], resultArray[2]));
}
scanner.close();
}
private static class Result
{
private String date;
private String time;
private String kg;
public Result(String date, String time, String kg)
{
super();
this.date = date;
this.time = time;
this.kg = kg;
}
public String getDate()
{
return date;
}
public String getTime()
{
return time;
}
public String getKg()
{
return kg;
}
}
}
Now you can pull out any information that you want to from the list of results that you have.
So if you wanted to print everything, you could do the following:
for(Result singleResult : results)
{
System.out.println(singleResult.getDate() + " " + singleResult.getTime() + " " + singleResult.getKg());
}
You basically can do whatever you want to with the data. This approach would also allow you to transform the data into different types before you even create the Result object.