How to simulate file IO in Java?
How can I create a class MockFile
mimicking java.io.File
w.r.t. file read and write? I using everywhere my own methods instead of new FileInputStream(....)
and new FileOutputStream(....)
, so this part is no problem (I always delegate to the appropriate stream). The non-trivila part is the implementation of my MockFileInputStream
and MockFileOutputStream
in more complicated cases.
There's is no problem, when I first write to a file and then read it, I can simply use a ByteArrayOutputStream
and so on. That's simple, but with interleaving reads and writes it can't work. Any better i开发者_Go百科dea than writing my own version of ByteArrayOutputStream
?
I would use a real file and a real FileInputStream
and FileOutputStream
. Otherwise you're just exercising test code: pretty pointless really.
I've created a 'WordCounter' class that counts the words in a file. However, I want to unit test my code and unit tests should not touch the file-system.
So, by refactoring the actual File IO (FileReader) into it's own method (let's face it, the standard Java File IO classes probably work so we don't gain much by testing them) we can test our word-counting logic in isolation.
import static org.junit.Assert.assertEquals;
import java.io.*;
import org.junit.Before;
import org.junit.Test;
public class WordCounterTest {
public static class WordCounter {
public int getWordCount(final File file) throws FileNotFoundException {
return getWordCount(new BufferedReader(new FileReader(file)));
}
public int getWordCount(final BufferedReader reader) {
int wordCount = 0;
try {
String line;
while ((line = reader.readLine()) != null) {
wordCount += line.trim().split(" ").length;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return wordCount;
}
}
private static String TEST_CONTENT = "Neque porro quisquam est qui dolorem\n"
+ " ipsum quia dolor sit amet, consectetur, adipisci velit...";
private WordCounter wordCounter;
@Before
public void setUp() {
wordCounter = new WordCounter();
}
@Test
public void ensureExpectedWordCountIsReturned() {
assertEquals(14, wordCounter.getWordCount(new BufferedReader(new StringReader(TEST_CONTENT))));
}
}
EDIT: I should note, if your tests share the same package as your code, you can reduce the visibility of the
public int getWordCount(final BufferedReader reader)
method so your public API only exposes
public int getWordCount(final File file)
精彩评论