0

I have a class FacebookDataExtraction that reads the data from the Excel file and stores the data as list of row objects as shown in the code. I have made use of the config.properties file to get the file path. The contents of config.properties file are:

FILE_NAME=D:/Refreshed_data_daily/all_hue_posts_in_excel.xlsx.

public class FacebookDataExtraction {

    //private static final String FILE_NAME="D:/Refreshed_data_daily/all_hue_posts_in_excel.xlsx";
    private static final String SHEET_NAME="nextv54plus_actions";
    XSSFWorkbook workbook;

    public static void main(String[] args){

        FacebookDataExtraction obj= new FacebookDataExtraction();
        List<FacebookFields> displayList= new ArrayList<FacebookFields>();
        displayList=obj.readFromExcelFile();
        System.out.println("The Size of the list is:"+ displayList.size());
        //System.out.println(displayList);
    }

    public List<FacebookFields> readFromExcelFile() {
        List<FacebookFields> fbList= new ArrayList<FacebookFields>();
        try
        {
            ReadPropertyFile data= new ReadPropertyFile("config.properties");
            FileInputStream fin= new FileInputStream(data.getPropertyFor("FILE_NAME"));
            workbook= new XSSFWorkbook(fin);
            int sheetIndex=0;
            for (Sheet sheet : workbook) {
                readSheet(sheet,sheetIndex ++, fbList);}

        }catch(FileNotFoundException e){
            e.printStackTrace();
        }
        catch(IOException e){
            e.printStackTrace();
        }
        return fbList;
    }

    public void readSheet(Sheet sheet, int sheetIndex , List<FacebookFields> fbList) {

        if(SHEET_NAME.equals(sheet.getSheetName())){
            workbook.removeSheetAt(sheetIndex);
            return;
        }
        for (Row row : sheet){
            if (row.getRowNum() > 0)
                fbList.add(readRow(row));}

    }

    private FacebookFields readRow(Row row) {

        FacebookFields record= new FacebookFields();
        for (Cell cell : row) {
            switch (cell.getColumnIndex()) {
            case 0: record.setName(cell.getStringCellValue()); 
            break; 
            case 1: record.setId(cell.getStringCellValue()); 
            break; 
            case 2: record.setDate(cell.getStringCellValue());
            break; 
            case 3: record.setMessage(cell.getStringCellValue());
            break; 
            case 4: record.setType(cell.getStringCellValue());
            break; 
            case 5: record.setPage(cell.getStringCellValue());
            break; 
            case 6: record.setLikeCount(String.valueOf(cell.getNumericCellValue()));
            break; 
            case 7: record.setCommentCount(String.valueOf(cell.getNumericCellValue())); 
            break; 
            case 8: record.setShareCount(String.valueOf(cell.getNumericCellValue())); 
            break; 
            default:System.out.println("Missing record at row :" + row.getRowNum() + " column :" +  cell.getColumnIndex() );

            }
        }

        return record;
    }

    public boolean containsData() {  

        List<FacebookFields> checkList= readFromExcelFile();    
        return !checkList.isEmpty() ;
    }

}

I have written test case to check if the list i.e fbList contains data after the method readFromExcelFile() is called.

@Test
    public void testWhetherListConatinsData(){
        FacebookDataExtraction fbDataList= new FacebookDataExtraction();
        assertEquals(fbDataList.containsData(), true);  
    }

I got suggestion that the method readSheet() can be tested by mocking the parameter Sheet sheet How do I test the method readSheet() I'm new to mocking, can anyone explain how it can be done for the method readSheet() with testcases for if and for loop both.

ShridharBavannawar
  • 164
  • 1
  • 3
  • 13

1 Answers1

0

You could create a stubbed Sheet; that is, create a class which extends Sheet and override the methods you want to influence.

As you have readSheet() marked with public accessor, you can just call: readSheet(<instance of your extended Sheet class>, sheetIndex, fbList)

Or you could use Mockito if you want to make this task simpler.

However, I think readSheet would be more suitable for a unit test if it returned something, rather than accessing a list from its caller, otherwise you can initialize a List<FacebookFields> in your test, and pass it into readSheet().

Community
  • 1
  • 1
Damien O'Reilly
  • 952
  • 5
  • 12
  • I'm not getting exactly how to do it. – ShridharBavannawar Oct 14 '15 at 11:53
  • To be honest, I think your class needs to be changed or restructured to support unit tests. For example `readSheet()` relies on global variable `workbook` which is only initialized in `readFromExcelFile()`. `readSheet()` relying on variables outside its own scope will make unit testing difficult and messy. – Damien O'Reilly Oct 14 '15 at 12:02
  • 1
    The workbook can be initialized in the _readFromExcelFile()_ . How do I initialize the parameter _List fbList_ in my test case? – ShridharBavannawar Oct 14 '15 at 12:38
  • Your `readSheet()` method depends on `readFromExcelFile()` initializing something for you. You can call `readFromExcelFile()` in your unit test setup, however this defeats the purpose of mocking Sheet, when you end up reading from the file system anyway. I would suggest to read up on unit tests and how to make methods more independent. – Damien O'Reilly Oct 14 '15 at 14:01
  • Any suggestions you have to modify the code? What I was thinking was the method _readSheet()_ will return the list of row objects such that the _workbook_ is defined and initialized with in the method. And rest all remains the same. I don't know whether it solves the problem because we will have the method _readRow_ left which is to be tested! – ShridharBavannawar Oct 15 '15 at 02:04