Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Pattern your way to automated regression testing

Implement popular design patterns to overcome unit-testing hurdles

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
We have all heard the mantra: test, test, test. Unit test all mission-critical business logic. If possible, write the unit tests before you write the code. Test everything you can, and test it often.

Frequent testing is one of the extreme programming fundamentals, a set of practices growing in popularity because it provides a sound approach to dealing with the inevitable complexity and change of today's programming projects. But the simple mantra to test is much easier said than done, and far more often preached than practiced. Deadlines approach, managers loom, and important testing gets postponed yet again.

In the past, a major obstacle to adequate unit testing was the inherent startup costs to design and implement an acceptable unit-testing framework. Without a framework, unit tests were haphazardly implemented, and very difficult to aggregate into test suites that ran with the click of a button. Fortunately, Erich Gamma and Kent Beck have implemented Beck's Smalltalk unit testing framework in Java, called JUnit. This excellent framework, already the de facto standard for implementing unit testing in Java, provides the basic plumbing for developers to quickly generate whole test suites that validate their programs with the click of a button. With JUnit, a major excuse for eschewing unit tests has been obviated.

"Trade"-offs

However, there is a more pernicious obstacle to unit testing system parts that involve access to a database system. As an example, imagine a system that processes trade transactions in a stock market simulator. One or more external systems place trade orders into a database, which our simulator then reads and processes. Assume our goal is to implement this system as well as all the unit tests necessary to ensure its smooth run. You can easily test certain system parts with JUnit.

Now consider the object that calculates the transaction's dollar value. The test could simply create a Trade object with the desired arguments, and then assert that the getPrice() method returns the expected amount. But what about the TradeProcessor object, which reads and processes the incoming database requests? Suppose myriad combinations of incoming trade orders have different outcomes in our simulator, and we wish to test those various combinations as part of our JUnit suite. Could you unit test that part of the system? (If you're not convinced you can by the end of this article, I haven't done my job!)

We could approach unit testing this core logic in several ways. We could set up multiple test databases (one for each test case), and between each unit test, change the database the program queries. We would have to ensure that those databases are immutable, since we want subsequent runs to produce identical results. If the system's nature is such that merely running a test causes the database to produce different results (for example, by setting the status of "pending" trades to "processed"), this approach is very problematic indeed. What's more, you would then have to somehow keep all those databases, with their precise state necessary for successful unit tests, stored with that source code version. For most source code revision-control tools, this requirement would present a major problem.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (1)
Login
Forgot your account info?

Great article, but...By Anonymous on January 27, 2009, 3:21 amTwo things: 1. Your singleton implementation seems to be thread-safe (you synchronized the constructor) but, in fact, it isn't. Neither put(), get() or the HashMap...

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources