Naked Objects
By Richard Pawson and Robert Matthews

Writing tests

Modern systems development practice now demands that testing be an integral part of the development process, conducted as early as possible, and automated to the greatest extent possible. In the Java world, the Junit framework has been one of the most significant enablers of this concept.

The following code shows one fairly obvious approach to writing unit tests for Naked Objects using Junit. This tests the bidirectional association between a booking and the customer, and the confirm option:

public void testBookingForCustomer() {
        Booking booking = new Booking();
        Customer customer = new Customer();

        booking.associateCustomer(customer);

        assertEquals(customer, booking.getCustomer());
        assertTrue(customer.getBookings().contains(booking));

        assertTrue(booking.aboutActionCheckAvailability().canUse().isAllowed());
        booking.actionCheckAvailability();
        assertEquals("Available", booking.getStatus().title().toString());
}

The code below re-writes this using 'mock' view objects, which are provided as part of the Naked Objects framework. Mock views represent the objects within test code in the same way that graphical views represent the objects within the basic GUI, i.e. they allow the objects to be manipulated as if a user were working interactively.

As above, we start by creating two new objects, a booking and a customer. This time, though, we create the new booking by getting a mock view of the booking class itself (using the name 'Bookings' that would normally be displayed under the class icon), and then performing the equivalent of right-clicking on the menu for that class and invoking the New Instance... option. We do the same for the customer:

public void testBookingForCustomer() {
        View booking = getClassView("Bookings").newInstance();
        View customer = getClassView("Customers").newInstance();

        booking.drop("Customer", customer.drag());

        booking.assertFieldContains("Customer", customer);
        customer.assertFieldContains("Bookings", booking);

        booking.rightClick("Check Availability");
        booking.assertFieldContains("Status", "Available");
}

The advantage of this approach over the previous Junit example is not only that the test code is simpler, but that the mock views test the functionality from the perspective of the user. Thus we no longer have to worry about whether to call the set... or the associate... method; we can just ask the mock view to simulate dropping an object onto the required field and let the framework decide which method needs to be called. The framework will now also check the about... method, if there is one, and if changing the field is disabled an exception will be thrown. Similarly, if a mock view is asked to invoke one of the business object's action methods, it will only do so after first checking the corresponding about... method to see if that action method is available in that context.

The example also shows some additional assert... methods that we have added to make the checking of the objects simpler. These methods allow us to specify fields using the names as they should appear to the user. This means we can write tests before we have written the methods that we will be testing, and to compile those tests without error. When the test is run, if no method is found to match the specified name, then an exception is thrown. Some programmers like to use this style of executable unit test to guide their development process - dealing with each exception in turn.