samedi 31 janvier 2015

Small code, big test


I have this code in a controller of an MVC implementation:



public void execute() {
try {
String path = userSelectsFile();
if ( path == null ) return; //Just returns if the user press "Cancel"

//Load the data
Collection<Info> infos = Infos.fromJSON(getInputReader(path));
//Show the data in the interface
new ShowTransformationsInTree(win(), infos, win().getTree()).execute();
} catch (Exception e) {
new ComplainAction(win(), "Unable to...blah, blah", e).execute();
}
}


To test this, I have to mock the user interface to show file dialog and make getInputReader method an abstract factory method.


So here goes the test:



/**
* Mocks the LoadTransformationsAction so the factory method getReader returns a ByteInputStream
*/
public class MockLoadTransformationsAction extends LoadTransformationsAction {
//CONSTRUCTOR REMOVED FOR CLARITY.....

@Override
protected InputStreamReader getInputReader(String path) {
assertEquals(FAKE_ABSOLUTE_PATH, path);
return new InputStreamReader(
new ByteArrayInputStream(TestHelpers.createDataBytes());
}
}

/**
* Test the proper loading of the data.
*/
@Test
public void testLoadData(@Mocked final FileChooser anyChooser) {
new Expectations() {{
//Mocks the IntelliJ idea API
FileChooser.chooseFile(null, null, null); result = new MyFakeVirtualFile(); //Returns a fixed path
}};

//Loads the data from the JSON file
MainToolWin m = new FakeMainToolWin();
LoadTransformationsAction action = new MockLoadTransformationsAction(
m, new FakeProject(), new MockInputProgram());
action.execute();

//Test that the transformations are in the UI Tree
DefaultTreeModel model = (DefaultTreeModel)m.getTree().getModel();
assertEquals(2, model.getChildCount(model.getRoot()));
assertEquals(3, model.getChildCount(model.getChild(model.getRoot(), 0)));
}


QUESTIONS


Am I doing to much to test to little?


As you can see there are mock and facke objects all the way, so much mocking can make my test unreliable?


A better design can be proposed?





Aucun commentaire:

Enregistrer un commentaire