Print Page | Close Window

Unit testing with mock objects

Printed From: One Stop Testing
Category: Types Of Software Testing @ OneStopTesting
Forum Name: Unit Testing @ OneStopTesting
Forum Discription: Discuss All that is need to be known about Unit Software Testing and its Tools.
URL: http://forum.onestoptesting.com/forum_posts.asp?TID=239
Printed Date: 06Jun2024 at 5:52am


Topic: Unit testing with mock objects
Posted By: Rohit
Subject: Unit testing with mock objects
Date Posted: 23Feb2007 at 4:26pm
Mock objects are a useful way to write unit tests for objects that act as mediators. Instead of calling the real domain objects, the tested object calls a mock domain object that merely asserts that the correct methods were called, with the expected parameters, in the correct order. However, when the tested object must create the domain object, we are faced with a problem. How does the tested object know to create a mock domain object instead of the true domain object? In this article, software consultants Alexander Day Chaffee and William Pietri present a refactoring technique to create mock objects based on the factory method design pattern.
< ="" ="text/">

http://www.ibm.com/developerworks/search/searchResults.jsp?source=google&searchType=1&searchSite=dW&searchScope=dW&query=Unit+Testing+ - More dW content related to: Unit Testing

Unit testing has become widely accepted as a "best practice" for software development. When you write an object, you must also provide an automated test class containing methods that put the object through its paces, calling its various public methods with various parameters and making sure that the values returned are appropriate.

When you're dealing with simple data or service objects, writing unit tests is straightforward. However, many objects rely on other objects or layers of infrastructure. When it comes to testing these objects, it is often expensive, impractical, or inefficient to instantiate these collaborators.

For example, to unit test an object that uses a database, it may be burdensome to install, configure, and seed a local copy of the database, run your tests, then tear the local database down again. Mock objects provide a way out of this dilemma. A mock object conforms to the interface of the real object, but has just enough code to fool the tested object and track its behavior. For example, a database connection for a particular unit test might record the query while always returning the same hardwired result. As long as the class being tested behaves as expected, it won't notice the difference, and the unit test can check that the proper query was emitted.

Mock in the middle

The common coding style for testing with mock objects is to:

  • Create instances of mock objects
  • Set state and expectations in the mock objects
  • Invoke domain code with mock objects as parameters
  • Verify consistency in the mock objects

While this pattern is very effective for many cases, sometimes the mock object cannot be passed into the object being tested. Instead, that object is designed to either create, look up, or otherwise obtain its collaborator.

For instance, the tested object may need to obtain a reference to an Enterprise JavaBean (EJB) component or remote object. Or the tested object may make use of objects with side effects that may not be desirable in unit testing, like File objects that delete files.

Common wisdom suggests that this situation provides an opportunity to refactor your object to make it more test-friendly. For instance, you may change the method signature so that the collaborator object is passed in.

In his article " http://www.ibm.com/developerworks/java/library/j-aspectj2/index.html - Test flexibly with AspectJ and mock objects ," Nicholas Lesiecki points out that refactoring is not always desirable, nor does it always result in code that is cleaner or easier to understand. In many cases, changing the method signature so the collaborator becomes a parameter will result in a confusing, untested snarl of code inside the method's original callers.

The heart of the problem is that the object is obtaining these objects "on the inside." Any solution must apply to all occurrences of this creation code. To solve this problem, Lesiecki uses a lookup aspect or a creation aspect. In this solution, the code that performs the lookup is replaced automatically with code that returns a mock object instead.

Because AspectJ is not an option for some, we offer an alternative approach in this article. Because this is, at root, a refactoring, we will follow the presentation convention established by Martin Fowler in his seminal book, Refactoring: Improving the Design of Existing Code (see http://www-128.ibm.com/developerworks/library/j-mocktest.html#resources - Resources ). (Our code is based on JUnit, the most popular unit testing framework for Java programming, though it is by no means JUnit-specific.)




Print Page | Close Window