Java Reference
In-Depth Information
Top-down development and testing is tricky —You must implement the collabora-
tors before you can write any of a class's unit tests. This, for example, makes
it impossible to develop and test a service before such as PlaceOrderService
before implementing the domain model classes that it calls. We are forced
to immediately dive into the details of the domain model.
Creating and initializing the collaborators makes a class's tests more complicated
Some objects require complex initialization in order to get them into the
correct state for a test. For example, if we wanted to test the scenario where
PlaceOrderService.updateDeliveryInfo() is called with the ID of a pend-
ing order that has already been placed, we would have to call multiple
methods on a PendingOrder to get it into the “Placed” state. This makes writ-
ing tests a lot more difficult.
Collaborators introduce undesirable coupling —For example, using real imple-
mentations of the repositories would couple the domain model to the data-
base and force us to address persistence issues. This is more complexity
than we should tackle at this point. Furthermore, the overhead of accessing
the database slows down the tests.
Fortunately, we can solve this problem by using mock objects . A mock object is a fake
implementation that is used solely for testing. A test will configure a mock object
to expect certain method calls and to return predetermined values. The mock
object will throw an exception if its expectations are not met. By using mock
objects, we simulate a domain object's collaborators without having to implement
them. Also, by mocking repositories, we do not have to deal with persistence
issues and can write tests that run without database. Using mock objects allows us
to simplify otherwise complex object interactions, enabling us to focus on one
piece of the application at a time.
If the class that you want to test invokes a collaborator via an interface, then
one way to implement a mock object is to simply define a fake class that imple-
ments that interface. A test case for PlaceOrderService , which uses the Restau-
rantRepository interface, could define a dummy class that implements the
RestaurantRepository interface, whose methods return test values. Although this
approach works well in very simple cases, writing the fake classes can easily
become pretty tedious. Moreover, you can only use this approach if there is an
interface to implement.
A much better way to implement mock objects is to use mock object testing
frameworks. Not only do they make it easier to write tests, but they also support
mocking of concrete classes. There are several mock object testing frameworks,
Search WWH ::




Custom Search