Home > database >  Testing for exceptions in Opencsv CSVReader
Testing for exceptions in Opencsv CSVReader

Time:11-13

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!

CodePudding user response:

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