tags:

views:

171

answers:

5

I have the piece of code that reads data from file. I want to force IOException in this code for testing purpose (I want to check if code throws correct custom exception in this case).

Is there a some way to create a file which is protected from being read, for example? Maybe dealing with some security checks can help?

Please, note that passing name to not-existent file cannot help, because FileNotFoundException has separate catch clause.

Here piece of code for better undestanding of question:

    BufferedReader reader = null;
    try {

        reader = new BufferedReader(new FileReader(csvFile));

        String rawLine;
        while ((rawLine = reader.readLine()) != null) {
            // some work is done here
        }

    } catch (FileNotFoundException e) {
        throw new SomeCustomException();
    } catch (IOException e) {
        throw new SomeCustomException();
    } finally {
        // close the input stream
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }
+1  A: 

You can always throw your own IOException:

throw new IOException("Test IOException");
Adam Batkin
I added code for original question. It seems that you didn't understand it.
DixonD
A: 

You could make this exception raise for a file that's too large.

thelost
A: 

You could try creating the file as a superuser and then reading it as a standard user. There should be permissions issues there. Or just chmod the thing assuming you're on Linux. You can also try putting it in a hidden / protected directory.

SB
Can you provide an example which will work on any target OS?
DixonD
Since OSes differ quite drastically in terms of what they do with their file systems and user management, it's tough. You could try using a java File object and calling setReadable / setWritable on it - see http://java.sun.com/javase/6/docs/api/java/io/File.html#setReadable%28boolean%29
SB
+1  A: 

If you can refactor the code slightly to accept a Reader, rather than a filename, you can use mocks. With EasyMock you can create a mock Reader, and set it to throw IOException upon calling any of its methods you wish. Then you just pass it to the method to be tested, and watch what happens :-)

void readFile(Reader reader) throws SomeCustomException {
    try {
        String rawLine;
        while ((rawLine = reader.readLine()) != null) {
            // some work is done here
        }

    } catch (FileNotFoundException e) {
        throw new SomeCustomException();
    } catch (IOException e) {
        throw new SomeCustomException();
    } finally {
        // close the input stream
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                // ignore
            }
        }
    }
}

then the test code:

mockReader = createMock(Reader.class);
expect(mockReader.readLine()).andThrow(
        new IOException("Something terrible happened"));
replay(mockReader);

objectToTest.readFile(reader);
Péter Török
It's a pity that I cannot change tested code
DixonD
A: 

You can use a Mock library like Mockito or Easymock (+classpath) to create a Mock file object (newer libs have classloader extensions that let you mock concrete classes like File), or can cooperate with something like PowerMock (see blog) and have a mock generated for the constructor call, and throw the appropriate exception when called.

jayshao
There is no way to pass the mock in the code
DixonD
Edited the answer to link to a blog entry on using PowerMock for this kind of testing (leverages ClassLoader manipulation)
jayshao