How to design a data driven JUnit test class - java

#Parameters
public static Collection data() throws IOException {
ArrayList<String> lines = new ArrayList();
URL url = PokerhandTestCase.class.getClassLoader().getResource("test/TestFile.txt");
File testFile = new File(url.getFile());
FileReader fileReader = new FileReader(testFile);
bufReader = new BufferedReader(fileReader);
assertFalse("Failed to load the test file.", testFile == null);
boolean isEOF = false;
while (!isEOF){
String aline = bufReader.readLine();
if (aline == null){
System.out.println("Done processing.");
isEOF = true;
}
lines.add(aline);
}
return Arrays.asList(lines);
}
The last line of the program is causing the crash, I would like to know what is the proper way to define a collection from a arrayList. This function is required to Collection as the return type.

Replace last line with this:
return (Collection)lines;
Since ArrayList implements Collection interface: http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html
So overall code:
public static Collection data() throws IOException
{
ArrayList<String> lines = new ArrayList();
// populate lines collection...
return (Collection)lines;
}
Based on the comments below, perhaps this would qualify as "Collection of arrays":
public static Collection data() throws IOException
{
ArrayList<String> array1 = new ArrayList();
ArrayList<String> array2 = new ArrayList();
ArrayList<String> array3 = new ArrayList();
// populate lines collection...
ArrayList<ArrayList<String>> lines = new ArrayList();
lines.add(array1);
lines.add(array2);
lines.add(array3);
return (Collection)lines;
}

ArrayList lines = new ArrayList();
...
return Arrays.asList(lines);
this return two-dimensional array.
This function is required to Collection as the return type.
I think user1697575's answer is correct.

Your collection that you are returning needs to be a Collection<Object[]>. You are returning a Collection. You need to do something like this (for a complete example):
#RunWith(Parameterized.class)
public class MyTest {
#Parameters
public static Collection<Object[]> data() throws IOException {
List<Object[]> lines = new ArrayList<>();
File testFile = new File("/temp/TestFile.txt");
FileReader fileReader = new FileReader(testFile);
BufferedReader bufReader = new BufferedReader(fileReader);
Assert.assertFalse("Failed to load the test file.", testFile == null);
boolean isEOF = false;
while (!isEOF) {
String aline = bufReader.readLine();
if (aline == null) {
System.out.println("Done processing.");
isEOF = true;
}
lines.add(new Object[] { aline });
}
return lines;
}
private final String file;
public MyTest(String file) {
this.file = file;
}
#Test
public void test() {
System.out.println("file=" + file);
}
}
Note that you're not closing the files here, and you're adding a useless null value to the end of the list, but I copied your code :-).

Related

Java method to read text file and return ArrayList type object

public static void main(String[] args)
{
ArrayList <Locations> LocationsList = readFile("Locations.csv", "Locations");
//ArrayList <Movies> MoviesList = readFile("Movies.csv", "Movies");
//ArrayList <Operators> OperatorsList = readFile("Operators.csv", "Operators");
//ArrayList <PersonCategory> PersonCategoryList = readFile("PersonCategory.csv", "PersonCategory");
}
public static ArrayList readFile(String fileName, String whichFile)
{
ArrayList list = new ArrayList();
try
{
BufferedReader br = new BufferedReader(new FileReader(fileName));
String indata;
int line = 0;
while((indata=br.readLine())!=null)
{
StringTokenizer st = new StringTokenizer(indata,",");
if(line != 0)
{
if(whichFile.equals("Locations"))
{
int id = Integer.parseInt(st.nextToken());
String city = st.nextToken();
if(city.charAt(0) == '"')
{
String c = st.nextToken();
city = city.substring(1,city.length()) +"," +c.substring(0,c.length()-1);
}
int stateId = Integer.parseInt(st.nextToken());
Locations x = new Locations(id, city, stateId);
list.add(x);
}
else if(whichFile.equals("Movies"))
{
int id = Integer.parseInt(st.nextToken());
String name = st.nextToken();
int ratingId = Integer.parseInt(st.nextToken());
Movies x = new Movies(id, name, ratingId);
list.add(x);
}
}
line++;
}
br.close();
}
catch (FileNotFoundException fnfe){System.out.println(fnfe.getMessage());}
catch (IOException io){System.out.println(io.getMessage());}
catch (Exception e){System.out.println(e.getMessage());}
return list;
}
I'm trying to create a method that will read a text file and can return an ArrayList type object for the usage of multiple Class. With my code above, it can run successfully.
But, there are lines of warning like:
"The expression of type ArrayList needs unchecked conversion to conform to ArrayList<Locations>"
How do I fix this?
Try this.
public static <T> ArrayList<T> readFile(String fileName, Function<String[], T> converter) throws IOException {
ArrayList<T> result = new ArrayList<>();
try (BufferedReader reader = Files.newBufferedReader(Paths.get(fileName))) {
String line = reader.readLine();
String[] fields = line.split(",");
T object = converter.apply(fields);
result.add(object);
}
return result;
}
and define the converters which convert a CSV line to an object.
static Locations convertLocations(String[] fields) {
int id = Integer.parseInt(fields[0]);
String city = fields[1];
if (city.charAt(0) == '"') {
String c = fields[2];
city = city.substring(1, city.length()) + "," + c.substring(0, c.length() - 1);
}
int stateId = Integer.parseInt(fields[3]);
Locations x = new Locations(id, city, stateId);
return x;
}
static Movies convertMovies(String[] fields) {
/* Make Movies object from fields */
}
and combine them.
ArrayList<Locations> LocationsList = readFile("Locations.csv", fields -> convertLocations(fields));
ArrayList<Movies> MoviesList = readFile("Movies.csv", fields -> convertMovies(fields));
You need to create the proper generics-based ArrayList using for example: new ArrayList<Location>()
You could solve this by passing a class to readFile like this:
public static <T> ArrayList<T> readFile(....., Class<T> clazz)
{
ArrayList<T> list = new ArrayList<T>();
...
}
This is my final code that I took from #saka1029 and made some adjustments so that it will read every line in the file except the first one.
public static <T> ArrayList<T> readFile(String fileName, Function<String[], T> converter)
{
ArrayList <T> list = new ArrayList<>();
try
{
BufferedReader br = new BufferedReader(new FileReader(fileName));
br.readLine();
String inData;
while((inData=br.readLine()) != null)
{
String[] fields = inData.split(",");
T object = converter.apply(fields);
list.add(object);
}
br.close();
}
catch (FileNotFoundException fnfe){System.out.println(fnfe.getMessage());}
catch (IOException io){System.out.println(io.getMessage());}
catch (Exception e){System.out.println(e.getMessage());}
return list;
}
And this is my version of the correction of the method convertLocations from #saka1029 answer.
static Locations convertLocations(String[] fields)
{
int id = Integer.parseInt(fields[0]);
String city = fields[1];
int stateId;
if (city.charAt(0) == '"')
{
String c = fields[2];
city = city.substring(1, city.length()) + "," + c.substring(0, c.length() - 1);
stateId = Integer.parseInt(fields[3]);
}
else
stateId = Integer.parseInt(fields[2]);
Locations x = new Locations(id, city, stateId);
return x;
}
Essentially, you need to specify the type parameter for generic class ArrayList.
Since you are adding objects created from different classes to the same list, you could create an interface, say, MyInterface
public interface MyInterface {
....
}
All classes you return from readFile must implement this interface. For eg.
public class Movies implements MyInterface {
....
}
Now, you can add type parameter MyInterface at appropriate places:
public static void main(String[] args) {
ArrayList<MyInterface> LocationsList = readFile("Locations.csv", "Locations");
....
}
public static ArrayList<MyInterface> readFile(String fileName, String whichFile) {
ArrayList<MyInterface> list = new ArrayList<>();
....
}
Added below info based on reply
You may in fact choose to leave the interface blank, but then you will have to explicitly cast objects to concrete classes to do anything useful.
You could cast each object when needed
MyInterface myInterfaceObject = locationsList.get(0)
Locations locations = Locations.class.cast(myInterfaceObject);
OR
MyInterface myInterfaceObject = locationsList.get(0)
Locations locations = (Locations) myInterfaceObject;
OR You could write a list converter function for each concrete type
public class ListConverter {
public ArrayList<Locations> toLocationsArraylist(ArrayList<MyInterface> inList) {
ArrayList<Locations> outList = new ArrayList<>();
for (MyInterface listItem : inList) {
outList.add((Locations) listItem);
}
return outList;
}
}
and then
public static void main(String[] args) {
ArrayList<MyInterface> myInterfaceList = readFile("Locations.csv", "Locations");
ArrayList<Locations> locationList = ListConverter.toLocationsArraylist(myInterfaceList);
}
If you do consider using this solution, then consider renaming MyInterface more appropriately, say, to CsvRecord, or anything domain-specific.

Why I can't show my list from another method?

Can you tell me why I can't see my list when I try to start it from another method? Below methods:
public class CollectionsOperation {
private List<Client> bufferedReaderClientLIst = new ArrayList<Client>();
private List<Client> emptyBoxForCf = new ArrayList<Client>();
BufferedReader bf = null;
private static final String fileName = "Clients.txt";
public List<Client> bufferedReaderCollection() throws IOException {
String line;
bf = new BufferedReader(new InputStreamReader (new FileInputStream(fileName), "UTF-8"));
while((line = bf.readLine()) != null) {
String[] split = line.split(";");
String nameCompany = split[0].substring(2);
String adress = split[1];
String phoneNumber = split[2];
String emailAdress = split[3];
Client k = new Client(nameCompany, adress, phoneNumber, emailAdress);
bufferedReaderClientLIst.add(k);
}
System.out.println(bufferedReaderClientLIst);
return bufferedReaderClientLIst;
}
public void show() throws IOException {
CollectionsOperation k = new CollectionsOperation();
k.bufferedReaderCollection();
System.out.println(bufferedReaderClientLIst);
}
Calling the method:
public static void main(String[] args) throws IOException {
CollectionsOperation k = new CollectionsOperation();
k.show();
}
And this is the result what I get:
[ MarkCompany';Ilusiana';0982882902';mark#company.com, CorporationX';Berlin';93983';X#Corporation.com]
[]
Why the second list is empty ? the method bufferedReaderCollection() returns a result and the list bufferedReaderClientLIst is available to all methods. What is wrong?
In show():
public void show() throws IOException {
CollectionsOperation k = new CollectionsOperation();
k.bufferedReaderCollection();
System.out.println(bufferedReaderClientLIst);
}
You create another CollectionsOperation object to call bufferedReaderCollection() on. This is unnecessary.
However the problem is in the last print statement where you print bufferedReaderClientList. This is printing the bufferedReaderClientList of the this instance, not k. Because you have not called bufferedReaderCollection on this, the list will be empty, hence the [] printed at the end.
Instead of creating another instance, use this:
public void show() throws IOException {
this.bufferedReaderCollection();
System.out.println(bufferedReaderClientLIst);
}

Retrieving random element in ArrayList

public class guessMovies {
private Random randomGenerator;
public static void main(String[] args) throws IOException {
String MovieList = null;
try (BufferedReader br = new BufferedReader(new FileReader("Movielist.txt"))) {
while ((MovieList = br.readLine()) != null) {
ArrayList<String> MovieNames = new ArrayList<String>();
MovieNames.addAll(Arrays.asList(MovieList));
//System.out.println(MovieList);
System.out.println(MovieNames);
Random r = new Random();
System.out.print(MovieNames.get(r.nextInt(MovieNames.size)));
}
}
catch(FileNotFoundException exception) {
System.out.println("I cannot find your file");
}
//pick random movie
}
Can somebody guide me on how to pick a random movie title in the Movielist file, I can print out the whole list, but I'm not sure on how to pick one of them randomly.
You should instantiate one ArrayList, read all movie titles and add them to the list, then use Random.nextInt() to pick one and print it.
Try something like this:
public class guessMovies {
public static void main(String[] args) throws IOException {
String MovieList;
ArrayList<String> MovieNames = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("Movielist.txt"))) {
while ((MovieList = br.readLine()) != null) {
MovieNames.add(MovieList);
}
for(String movieName: MovieNames){
System.out.println(movieName);
}
Random r = new Random();
System.out.println(MovieNames.get(r.nextInt(MovieNames.size())));
}
catch(FileNotFoundException exception) {
System.out.println("I cannot find your file");
}
//pick random movie
}
}

Returning an arraylist to be accessed from another class

I'm new to Stackoverflow, so here goes.
I'm currently working on an assignment that requires to read from a csv file and place it into some sort of data collection.
I've gone with an arraylist. But what I seem to be stuck with is that I'm attempting to use my ReadWriteFile class to read the csv file into an arraylist (which works). But I need to somehow access that array in my GUI class to fill my JTable with said data.
After looking through similar help requests, I haven't been able to find any success.
My current code from my ReadWriteFile class;
public static void Read() throws IOException {
String lines = "";
String unparsedFile = "";
String dataArray[];
String col[] = { "COUNTRY", "MILITARY", "CIVILIAN", "POWER" };
FileReader fr = new FileReader("C:/Users/Corbin/Desktop/IN610 - Assignment 1/Programming3_WWII_Deaths.csv");
BufferedReader br = new BufferedReader(fr);
while ((lines = br.readLine()) != null) {
unparsedFile = unparsedFile + lines;
}
br.close();
dataArray = unparsedFile.split(",");
for (String item : dataArray) {
System.out.println(item);
}
ArrayList<String> myArrayList = new ArrayList<String>();
for (int i = 0; i < dataArray.length; i++) {
myArrayList.add(dataArray[i]);
}
}
So what my question is; How can I create a method that returns the values from the array, so I can access that array in my GUI class and add each element to my JTable?
Thanks!
Here is some simple example of how to return array in the method and how to use it in GUI class:
public class Main {
public String[] readFromFile (String filePath) {
ArrayList<String> yourList = new ArrayList<String>();
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
// read file content to yourList
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return yourList.toArray(new String[yourList.size()]);
}
}
And the GUI class:
public class GUI extends JFrame {
private JTable jTable;
public GUI() {
jTable = new JTable(10, 10);
this.getContentPane().add(jTable);
this.setVisible(true);
this.pack();
}
public void passArrayToTable(Main mainClass) {
String[] array = mainClass.readFromFile("C:\\file.csv");
// for (String s : array) {
// add values to jTable with: jTable.setValueAt(s,row,column);
// }
}
public static void main(String[] args) {
new GUI().passArrayToTable(new Main());
}
}

Error while running customized java class

I have created a sequence file out of directory and then given index according to groups I want so that I can create groups using that index. This groups are then given one by one to my customized java class which gives information based on the file present in the group.
My problem is that some time it runs perfectly but some time gives different errors like null pointer exception, data type of field not found.
The problem is may be due to size of group. Because I am creating folder based group and then do the fetches the information from that folder inside my customized jar.
So how can I resolve this issue?
Below is my java class code:
public class OperateDirectory extends EvalFunc<DataBag>{
public TupleFactory tupleFactory = TupleFactory.getInstance();
public BagFactory bagFactory = BagFactory.getInstance();
public DataBag exec(Tuple input) throws IOException{
ArrayList<String> protoTuple = new ArrayList<>();
DataBag dataBag = bagFactory.newDefaultBag();
/* Create Directory */
if(input == null)
return dataBag;
if(input.size() != 2)
return dataBag;
long id = (long)input.get(0);
DataBag infoBag = (DataBag)input.get(1);
Iterator<Tuple> it = infoBag.iterator();
File dir = new File("/tmp/TestFolder"+id);
if(dir.exists())
{
FileUtils.cleanDirectory(dir);
}
else
{
dir.mkdir();
}
while(it.hasNext())
{
Tuple file_details = (Tuple)it.next();
if(file_details != null && file_details.size()==3)
{
String file_name = (String)file_details.get(1);
BytesWritable file_contents = (BytesWritable)file_details.get(2);
File f = new File(dir.getPath()+"/"+file_name);
f.deleteOnExit();
writeToFile(file_contents, f);
}
}
/* Perform operation here */
File f = new File("output"+id+".log");
ProcessBuilder performProcess1 = new ProcessBuilder("processes/processor", dir.getPath(),f.getPath());
Process process1 = performProcess1.start();
try
{
process1.waitFor();
if(f.exists() && f.length()>0)
{
ProcessBuilder performProcess2 = new ProcessBuilder("perl", "scripts/ParseFile.pl", f.getPath());
Process process2 = performProcess2.start();
InputStream is = process2.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null)
{
if(!line.isEmpty())
{
String [] tmpArray = line.split(",");
if(tmpArray.length == 2)
{
protoTuple.clear();
protoTuple.add(tmpArray[0]);
protoTuple.add(tmpArray[1]);
dataBag.add(tupleFactory.newTuple(protoTuple));
}
}
}
}
else
{
protoTuple.clear();
protoTuple.add("Error");
protoTuple.add("File "+f.getPath()+" does not exists ");
dataBag.add(tupleFactory.newTuple(protoTuple));
}
}
catch(Exception e)
{
protoTuple.clear();
protoTuple.add("Error ");
protoTuple.add(e.getMessage());
dataBag.add(tupleFactory.newTuple(protoTuple));
}
try
{
FileUtils.cleanDirectory(dir);
FileUtils.deleteDirectory(dir);
}
catch(Exception e)
{
}
return dataBag;
}
void writeToFile(BytesWritable value, File binaryFile) throws IOException{
FileOutputStream fileOut = new FileOutputStream(binaryFile);
fileOut.write(value.getBytes(), 0, value.getLength());
fileOut.close();
}
}

Categories