This version 0.12.3 (040611)
import java.awt.*;
import javax.swing.*;
import junit.framework.*;
import junit.extensions.abbot.*;
import abbot.script.ComponentReference;
import abbot.tester.ComponentTester;
public class LabeledListTest extends ComponentTestFixture {
public void testLabelChangedOnSelectionChange() throws Throwable {
String[] contents = { "one", "two", "three" };
final LabeledList labeledList = new LabeledList(contents);
Frame frame = showFrame(labeledList);
// ...
}
public LabeledListTest(String name) { super(name); }
public static void main(String[] args) {
TestHelper.runTests(args, LabeledListTest.class);
}
}
This won't compile until we get a LabeledList to test against, so let's do
that.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
public class LabeledList extends JPanel {
private JList list;
private JLabel label;
public LabeledList(String[] initialContents) {
setLayout(new BorderLayout());
list = new JList(initialContents);
add(list, BorderLayout.CENTER);
label = new JLabel("Selected: ");
add(label, BorderLayout.SOUTH);
}
}
Now we go back and add to the test. We want to select a list item and ensure
that the label reflects the selected item. So we first look up the list.
Note that while we could make the LabeledList member public or otherwise
directly accessible, that's making private data visible solely for the sake of
a test, and ends up cluttering the interface. Let the Abbot framework do the
work instead...
import abbot.finder.matchers.*;
...
public void testLabelChangeOnSelectionChange() throws Exception {
// ...
// The interface abbot.finder.Matcher allows you to define whatever
// matching specification you'd like. We know there's only one
// JList in the hierarchy we're searching, so we can look up by
// class with an instance of ClassMatcher.
Component list = getFinder().find(new ClassMatcher(JList.class));
Abbot will search the available GUI hierarchy until the first match is found
(you can use the abbot.finder.MultiMatcher
interface if there
might be more than one match). You can customize the matching
criteria to whatever fits your needs. You can also optimize the
search by providing a starting component as the first argument to
find
.
In order to play actions on the list, we want a ComponentTester object that
knows how, so we can create a JListTester (or let the ComponentTester do it
and cache the result for future tests).
JListTester tester = new JListTester();
tester.actionSelect(list, new JListLocation(1));
// or select by value
// tester.actionSelect(list, new JListLocation("two"));
At this point the selection has finished and any listening events propagated,
so you can check the results:
// We could also use an instance of ClassMatcher, but this shows
// how you can put more conditions into the Matcher.
JLabel label = (JLabel)getFinder().find(labeledList, new Matcher() {
public boolean matches(Component c) {
return c.getClass().equals(JLabel.class)
&& c.getParent() == labeledList;
}
});
assertEquals("Wrong label after selection",
"Selected: two", label.getText());
}
Now run the test. It will fail, because we haven't implemented anything in
the LabeledList to update the label when a selection is made. We do so
now.
public LabeledList(String[] initialContents) {
// ...
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent lse) {
label.setText("Selected: " + list.getSelectedValue());
}
});
}
Recompile and the test should now pass.