Java Development News:
JUnit In Action
By Dion Almaer
01 Nov 2003 | TheServerSide.com
When I first started to read JUnit in Action1, I was hoping that it wouldn't be a tutorial on the open source tool JUnit2. I am glad to say that it is much more. I think the book's name could really be "Testing in Practice". Sure, JUnit is covered in a lot of detail, but so are other tools such as:
- Integration with: Ant3, Maven4, and Eclipse5
- Mock Objects (via both EasyMock6 and DynaMock7)
- Cactus8 for testing in a container
- And other small helper tools (nice ant tasks, etc.)
What made me really enjoy this book is the way it is written, coupled with the practical look at the many technologies involved in testing. It is a fresh read, that doesn't get bogged down. The book flows really well, giving you best practices throughout. They don't just say "Do X", they actually show you where these best practices come from as they refactor their own code. You are really aware that these authors know their stuff, and are drawing from a lot of experience (compared to the online FAQs).
There is a little something for everyone, even if you are a beginner, and want to understand more about testing in general, how to start doing some Test Driven Development9, learn more about JUnit itself, or understand Mock Objects.
There is an art to testing. Using JUnit itself is easy. Writing GOOD tests, knowing WHEN to test, and knowing HOW to best test your projects, is where it gets harder. I think the book does a good job getting across some of this valuable information. You will probably find yourself having a few "Ahh, that makes sense... I should refactor my code here to do ..." moments. JUnit has been around awhile, and lots of us have been using it for some time, but this is definitely still worth a read. You may be able to skim through some of the beginning chapters, but having a fresh take is always good.
Let's look at the structure of the book:
PART ONE: JUnit Distilled
1. JUnit Jumpstart
2. Exploring JUnit
3. Sampling JUnit
4. Examining software tests
5. Automating JUnit
PART TWO: Testing Strategies
6. Coarse-grained testing with stubs
7. Testing in isolation with mock objects
8. In-container testing with Cactus
PART THREE: Testing Components
9. Unit-testing Servlets and filters
10. Unit-testing JSPs and taglibs
11. Unit-testing database applications
12. Unit-testing EJBs
A. The source code
B. Eclipse quick start
Let's look at these sections in detail.
Part One: JUnit Distilled
The book starts by delving into JUnit right away. JUnit Jumpstart has you understanding the history of JUnit, installing and configuring it on your system, and then writing a simple unit test. If you know your TestCases from your TestSuites, then you will breeze through this.
Exploring JUnit goes into more depth. If you'd like to know the JUnit lifecycle and really understand everything that is going on under the covers this is a chapter for you.
The first two chapters are good introductory pieces, but it starts to get going in Chapter 3. Here we get to writing some "real" code. The authors walk you through writing a controller based system, and you feel like you are following an experience. You are taught what makes good separation of test*() methods, and the best practices should be noted by unit testing beginners. Already we are faced with the question "Should you change your application to help you test?". This comes up a few times throughout the book, and the authors give a strong "YES". You can tell that they are proponents of Test Driven Development, and they explain their reasoning. They see your JUnit tests as the first users of the business code. Since the customer is always right, you should "let the test improve the code".
I sometimes find that a book falls in a few categories:
- Lots of code, no mention on how to run any of it.
- Lots of code, and they KEEP showing entire build files.
- No code. No help.
This book fits in between the first two. There is a good amount of code, and the authors do go into some details on the practical things. Items that you have to deal with like "Where should we put the tests? In the same package? Where on the file system? ..." They recommend using the same packages as your business code (so you have package access!), but putting your tests in another directory, keeping a clean separation. I happen to use this best practice myself, and it works great.
By the time that you are through the first three chapters, you should feel pretty educated when it comes to JUnit. Examining software tests changes direction a little, and gets into the interesting world of testing. Here we delve deeper to understand the various areas of testing (from unit tests to acceptance tests) and how they fit into the development cycle. We are shown why we are even BOTHERING with unit tests, and how much test coverage is enough. We finish up with a look at Test Driven Development itself, and how it changes the entire development cycle (and maybe your way of thinking?).
Automating JUnit concludes part one, covering the practical topics of integration. Here we work with the Ant, Maven, and Eclipse tools. For some people, this may be a first look at Maven.
Part Two: Testing Strategies
In my opinion, here it gets even more interesting. This part of the book gets into HOW best to do some of this testing. It is easy to test a hello world component, but life isn't that simple. We work with web servers, databases, and containers in general. How do we "get in there" to test our components?
Coarse-grained testing with stubs goes down the path of writing stubs, which are defined as "a portion of code that is inserted at runtime in place of the real code, in order to isolate calling code from the real implementation. The intent is to replace a complex behaviour with a simpler one that allows independent testing of some portion of the real code".
As we walk through a real world example of using stubs, we quickly learn that:
- Stubs get complicated
- Stubs don't lend themselves to fine-grained unit testing
- Stubs can be OK for integration testing (coarse-grained)
- Stubs may be a good choice if you don't want to touch the system itself
We then move on to the new wave in testing: Mock Objects10. Now we see how this strategy doesn't suffer the downsides of using stubs. It also has the side effect of showing how you end up using the Inversion of Control11 pattern all over. This is one reason that people are enjoying the new frameworks such as Spring12 and PicoContainer13. Inversion of Control has a great benefit of really enabling easy unit testing of your components. You really get to see this as you walk through the practical example using Mocks. Again, it is great to see real code instead of: no code, or silly code. The examples even show you some of the mock frameworks that are out there: EasyMock and DynaMock. Here (and throughout) we are shown pros and cons to help us understand what to use where.
Although the authors obviously seem to be fans of Mocks, they do understand some limitations, and this is how they get to In-container testing with Cactus. It is a good practice to have tests that really run inside a container, as that is what happens in your real world. Mocks can do the fine grained component tests, but using Cactus will find those bugs that show up due to the work that the container is doing (and some of them seem to have a fair few bugs don't they!). This chapter will give you a good understanding of the Cactus open source testing framework (as it should with the creator as an author).
At this point we have good ideas on when to use various techniques. And then we move to...
Part Three: Testing Components
I like to roll up the sleeves a little and get dirty don't you? I hate it when a book doesn't do the same. This chapter gets dirty as it goes into the details of combining testing with the various J2EE APIs.
As we have mentioned, writing some tests for that nice component that sits in a lightweight container is one thing, but I use EJBs, and JSPs, and tag libraries, and everything else in the J2EE toolbox!
These last chapters get dirty and walk through testing with these technologies. Here you will take your knowledge of Mocks, Cactus, and JUnit, and will really stretch it in a practical way. You will also learn new helpful systems along the way, such as DbUnit14 for helping you unit test with the data tier. This is really great stuff.
I would definitely recommend JUnit in Action for anyone interested in testing their code (which is hopefully a lot of you!). It is a book that you will find flows nicely, and offers a great mix of technology theory, and how to put it all to practice. It even covers a lot more than I was able to talk about in this summary. Great work Vincent and Ted!
Here are links to areas that I mention in the book report:
- JUnit In Action's book home page: http://www.manning.com/massol/
- JUnit the framework: http://www.junit.org
- Ant: http://ant.apache.org
- Maven: http://maven.apache.org
- Eclipse: http://www.eclipse.org
- EasyMock: http://www.easymock.org
- DynaMock: http://www.mockobjects.com/wiki/DynaMock
- Cactus: http://jakarta.apache.org/cactus
- Test Driven Development: http://www.c2.com/cgi/wiki?TestDrivenDevelopment
- Mock Objects: http://www.mockobjects.com
- Inversion of Control: http://javangelist.snipsnap.org/space/IoC
- Spring Framework: http://www.springframework.org
- PicoContainer: http://www.picocontainer.org
- DbUnit: http://dbunit.sourceforge.net
Gump: Continuous builds: http://jakarta.apache.org/gump
Source code for the book: http://sourceforge.net/projects/junitbook
About the Author
Dion Almaer (firstname.lastname@example.org) is a Principal Technologist for The Middleware Company (www.middleware-company.com), one of the nation's leading training companies in EJB/J2EE and B2B technology training. TheServerSide.Com J2EE Community is a service of The Middleware Company.