Section 32.4. The Adapter


32.4. The Adapter

Initially, Emily had encoded the GUI operations directly in the fixture, but she had realized that it would be better to have an adapter. The adapter code is shown in Listing 32.2. This code uses a GuiAdapter[3] to operate on the components, such as JButtons, of the running GUI.

[3] This general-purpose class is available as a part of the FitLibrary.

The adapter provides two API methods, as called from the fixture. The first method, addRentalItem(), emulates the operations of the user through the GUI, as shown in Figure 32.2, to add the details of a new rental item.

  • pressTab() clicks the second tab of the named JTabbedPane.

  • pressButton() clicks the Add button now showing.

  • getAdapterForFirstDialog() returns a GuiAdapter for the dialog that's expected to show, as shown in Figure 32.3.

  • enterString() is used three times to enter text into named JTextFields in the dialog. The strings are as supplied from the Fit table.

  • pressButton() clicks the Add button on the dialog to complete the data entry.

This GuiAdapter depends on the Swing components of interest being explicitly named. For example, the first JTextField is named "nameField", as shown in part of the code for the dialog box in Listing 32.3.

The second method of class RentEzeUiAdapter, getrentalItems(), is shown in Listing 32.2. This method passes the actual collection from the JTable, named "table", to a SetFixture. This method makes use of the general-purpose method collectionOfJTable() in class GuiAdapter, which takes the internal name of a JTable and returns a list of Map objects, one for each row in the table. A Map defines, for a row, the mapping between each JTable column name and the corresponding value from the table.

Listing 32.2. RentEzeUiAdapter.java
 public class RentEzeUiAdapter {    GuiAdapter frameAdapter;    public RentEzeUiAdapter(JFrame frame) {       frameAdapter = new GuiAdapter(frame);    }    public void addRentalItem(String name, int count,           double hourlyRate) throws Throwable {        frameAdapter.pressTab("tabbedPane",1); // Press tab for Rental        frameAdapter.pressButton("addButton");        GuiAdapter dialogAdapter = frameAdapter.getAdapterForFirstDialog();        dialogAdapter.enterString("nameField",name);        dialogAdapter.enterString("count",""+count);        dialogAdapter.enterString("hourlyRateField",""+hourlyRate);        dialogAdapter.pressButton("addButton");    }    public List getRentalItems() throws Throwable {        frameAdapter.pressTab("tabbedPane",1); // Press tab for Rental        return frameAdapter.collectionOfJTable("table");    } } 

Listing 32.3. EditRentalItemDialog.java
 public class EditRentalItemDialog extends JDialog {    private JTextField nameField = new JTextField(20);    private JTextField countField = new JTextField();    private JTextField hourlyRateField = new JTextField();    public EditRentalItemDialog(JFrame frame, RentalItem item) {       super(frame, "Edit Rental Item", false);       // ...       nameField.setName("nameField");       hourlyRateField.setName("hourlyRateField");       countField.setName("count");    }    // ... } 

Figure 32.4 shows the interaction during setup of the first two tables of Figure 32.1 and the fixture, GUI, and application objects.

Figure 32.4. Testing Through the GUI


Note

The adapter acts as mapping layer that maps each API action into a sequence of operations on the GUI. Having a separate layer means that we can write the fixtures for the intended API, as it develops. Once this mapping layer is in place for a part of the API, the corresponding part of the system can be untangled. Once we have a means of switching the tests so that they can be run through the GUI or the API or both, we can be sure that mistakes aren't introduced and left.


Note

SetFixture, ArrayFixture, and SubsetFixture all interpret Map objects in an actual collection in a special way, as introduced in Section 28.9 on p. 243. Instead of checking for an instance variable or a property that corresponds to the Fit table header name, the fixture looks for a mapping from that name to a value. For consistency with the treatment of table headers, extended camel casing[a] is applied to a JTable column name before it is used as a key into the Map.

[a] See Section 22.2 on p. 190 for an introdution to extended camel casing.




    Fit for Developing Software. Framework for Integrated Tests
    Fit for Developing Software: Framework for Integrated Tests
    ISBN: 0321269349
    EAN: 2147483647
    Year: 2005
    Pages: 331

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net