When writing a class it sometimes happens that you have to write a method which invokes methods of the same instance. I was wondering how to test those methods in isolation. Here is an abstract example demonstrating the problem:
Class XYZ
- method doThisIfCase1OrThatOtherwise
- method doThis
- method doThat
Testing
doThis and
doThat should not be a problem. But testing
doThisIfCase1OrThatOtherwise without testing
doThis and
doThat again seemed impossible to me. Of course it would be possible to extract
doThis and
doThat into a separate class and then mock this class when testing
doThisIfCase1OrThatOtherwise. But there are cases doing this smells a bit like over engineering.
In cases I don't know what to do I ask Misko my test and clean code oracle. As always he provided me with a solution: Override the methods
doThis and
doThat and assert that they get called.
This is an example from my "real" world:
The class under test:
...
public void openAndCreateIfNotExists() throws IOException {
if (!destinationClassPathFile.exists()) {
createEmptyClassPathFile();
} else {
openExistingClassPathFile();
}
}
void createEmptyClassPathFile() {
eclipseClassPathDocument = DocumentHelper.createDocument();
eclipseClassPathDocument.addElement("classpath");
}
void openExistingClassPathFile() throws IOException {
SAXReader reader = new SAXReader();
try {
eclipseClassPathDocument = reader.read(destinationClassPathFile);
} catch (DocumentException e) {
throw new IOException("Invalid class path file " + destinationClassPathFile.getCanonicalPath(), e);
}
}
...
The test:
@Test
public void testOpenAndCreateIfNotExistsCreates() throws IOException {
File file = new File("src-test/testOpenAndCreateIfNotExistsCreates.testFile");
if (file.exists())
file.delete();
file.deleteOnExit();
assertFalse(file.exists());
final StringBuilder stringBuilder = new StringBuilder();
EclipseClassPathManipulator eclipseClassPathManipulator = new EclipseClassPathManipulator(file) {
@Override
void createEmptyClassPathFile() {
stringBuilder.append("igotcalled");
}
};
eclipseClassPathManipulator.openAndCreateIfNotExists();
assertEquals("igotcalled", stringBuilder.toString());
}
@Test
public void testOpenAndCreateIfNotExistsOpens() throws IOException {
final StringBuilder stringBuilder = new StringBuilder();
File file = new File("src-test/testOpenAndCreateIfNotExistsOpens.testFile");
file.createNewFile();
file.deleteOnExit();
assertTrue(file.exists());
EclipseClassPathManipulator eclipseClassPathManipulator = new EclipseClassPathManipulator(file) {
@Override
void openExistingClassPathFile() throws IOException {
stringBuilder.append("igotcalled");
}
};
eclipseClassPathManipulator.openAndCreateIfNotExists();
assertEquals("igotcalled", stringBuilder.toString());
}
Keine Kommentare:
Kommentar veröffentlichen