The “entry point” to JPicus. A well tested view.
From an end user point of view the “entry point” to JPicus is the AgentConnectionsView.
Similar to every view in JPicus, the AgentConnections view is 100% covered with unit tests. This view specifically has 95.9% (71 lines) covered with unit test and 12.1 % (9 lines) covered with an integration test.
First - the provided functionality:
The AgentConnections view allows the user to create a new connection to a JPicus agent. It can maintain more then one connection. For every connection the user can create a number of Snapshots (using the Take Snapshot action). Double click on the snapshot opens another view. There is also a context menu on every snapshot. Selecting the snapshot will give you the snapshot properties in the properties view.
Second - from an eclipse developer point of view we have:
TreeViewer, two actions in the view tool bar, context menu, double click listener (and action for the listener) and finally a selection provider.
Third - the Tests:
Unit testing the content and label provider is pretty straightforward and very domain specific. Testing the actions also - there are the IAction and IActionDelegate interfaces that allow for pretty well decoupling. But how do you test the view?
As every object the AgentConnections view has
- an input - the connections and snapshots to be shown (IConnectionsHolder)
- an output - the output is actually the viewer
- a helper - IActionFactory that helps decoupling the creation of actions from their use
- an error handler - in this case org.eclipse.core.runtime.ILog
In order to unit test the view you must inject the input,helper,error handler (preferably in the constructor). Do not leave the view to create this things by it self. Invert the dependency (DIP).
public AgentConnectionsView(IConnectionsHolder connections, IActionFactory actionFactory, ILog log) {
this.connections = connections;
this.log = log;
this.actionFactory = actionFactory;
}
Of course since this is a view it is registered in the plugin.xml. And it must have a default constructor. This could be implemented in a similar way and tested with an integration test:
public AgentConnectionsView() {
this(JPicusUI.getDefault().getConnectionsHolder(), new ActionFactory(), JPicusUI.getDefault().getLog());
}
Since every ViewPart is an WorkbenchPart it delegates its getAdapter(Class) method to Platform.getAdapterManager().getAdapter(this, adapter). This is the other method where you can not get away from the integration test.
All the other methods of a view can (and should) be unit tested. Having a good mock library (in my case easymock) you can easily mock IConnectionHolders, IActionFactory, ILog, IViewSite, IWorkbench etc. Since the IViewSite contains IActionBars, IToolBarManager, IMenuManager it is also straightforward to test that the correct actions are added to the tool bar.
The most challenging methods from AgentConnectionsView are createPartControl() and setFocus().
createPartControl(Composite)
Call this method in the following way in you tests.
Display.getDefault();
Shell shell = new Shell(Display.getDefault());
view.init(site);
view.createPartControl(shell);
And verify that the shell actually has some children (it this case a Tree). Although this involves creating a shell it won`t block your thread.
setFocus()
Given the following implementation of setFocus()
public void setFocus() {
viewer.getControl().setFocus();
}
implementing a unit test is more challenging. Fortunately there is a Control.addFocusListener(FocusListener) method. Using the FocusListener the test could be
public boolean verifySetViewFocus(IViewPart view) {
final boolean focus[] = new boolean[1];
focus[0] = false;
getViewer().getControl().addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
focus[0] = true;
}
});
view.setFocus();
// on Linux the focus listener is notified after the test completes. So
// start a new runnable that will wait for a little.
ModalContext.run(new IRunnableWithProgress() {
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
Thread.sleep(1);
}
}, true, new NullProgressMonitor(), Display.getDefault());
assertTrue(focus[0]);
}
As a result - the user interface can be tested. In Eclipse it has always been this way…
Posted June 14th, 2009 by kiril in category: JPicus
You can leave a response, or trackback from your own site.
Leave a Reply
You must be logged in using your Eclipse Bugzilla account to post a comment.


