jfcUnit Primer

How does jfcUnit work? First, it extends the JUnit test case in the JFCTestCase class; this class enables us to interact with the AWT thread so that we can start the app and run the tests interactively. If we attempted to do this with a standard JUnit test, we would run into the primary problem of waiting for the Swing app to start and interact with the right thread (JUnit tests typically execute in a separate thread). We might be able to do this with the Robot class that Sun provides in jdk1.3 and above (java.awt.Robot), but it is very limited in its capabilities. jfcUnit takes advantage of this by extending the Robot class in its RobotTestHelper class. JfcUnit also has two classes that assist us in discovering components and in performing actions on those components: Finder and TestHelper, respectively. A TestHelper instance (or one of its subclasses JFCTestHelper or RobotTestHelper) is created within the setUp() method, or outside of it in a private variable, so that it is available throughout the tests. An appropriate Finder class is instantiated like so:

Finder jTableFinder = new ComponentFinder(JTable.class);

This enables us to find the component that we want to test or contains sub-components we also want to interact with. Now let’s take a look at one of TestHelper’s subclasses JFCTestHelper and see what it does. Creating an instance of the helper is simple:

JFCTestHelper helper = new JFCTestHelper();

This essentially starts up the helper and keeps it in memory, ready to simulate a user’s actions on your Swing app. Some of these methods are:

More fine-grained methods, for handling key presses and mouse movements.

These are just a few of the methods in the TestHelper and JFCTestHelper sub-class; other methods include helper methods for getting all the dialogs open on the screen or all the currently open windows. So, how do these two work together? Simply use an appropriate Finder class for the type of component you are testing, in general this will be a ComponentFinder. Once you have found the appropriate component (a Swing component will get returned to you), you then use the JFCTestHelper to send events to it. So, a full round-trip would look something like this in your JUnit test class:

private JFCTestHelper helper = new JFCTestHelper();
 protected void setUp() throws Exception {
public void testTable(){
 JTabbedPane tabbedPane = selectTab("TableView"); Finder finder = new ComponentFinder(JTable.class);
 JTable table = (JTable)finder.find(tabbedPane, 0);
 JTableMouseEventData jtmed = new JTableMouseEventData(this, table, 0, 0, 1);
 assertTrue(((String)table.getValueAt( table.getSelectedRow(), table.getSelectedColumn())).equals("Mike")); }

As you can see it’s relatively straightforward, but I’ll walk through this a little bit. First, we set up our test by creating a JFCTestHelper, and then in the setUp() method we go ahead and start up our Swing app for testing. Next we step into the first test, testTable(), which we will go into further detail in the next section, “Testing a Swing app with jfcUnit.” The first thing we do in the test is to select the appropriate tab name, “TableView”, then we instantiate a new Finder for the JTable that contains that tab. Once we have the finder instantiated we use it to find the tabbedPane we previously defined and the first component in this tab, which is a JTable. This returns the JTable that we are looking to test, enabling us to now perform some action on it, such as an enterClickAndLeave. The JTableMouseEventData is another class that assists us with testing our Swing app by passing in the appropriate data to the AWT event stream for processing. awtSleep is called to pause the test so that the AWT event queue can process the event. Then we test to make sure that the proper value has been processed.