Testing: Cactus and JUnit
With the advent of Extreme Programming (XP) and its emphasis on refactoring, unit testing has gained in popularity and exposure. In order to refactor anything, a good set of unit tests must be in place to make sure that current clients of the implementation will not be affected by the changes that aremade. Many developers, as they embrace the XP approach, are suddenly “test infected” and writing all kinds of JUnit tests. Many developers who were doing unit testing with code in the main method of their Java classes are finding JUnit and Cactus to be a more thorough means to test their classes. This chapter is about what goes wrong when building a real-world test set for real-world applicationswith these tools. Many pitfalls in unit tests come from the complexity of the components being tested or the complexity of the tests themselves. Also, the lack of assertions in the test code can cause problems. Without an assertion, a test just confirms that no exceptions were thrown. Although it is useful to know when exceptions are thrown, it is rarely enough. For example, not all unexpectedstate changes in a test subject will throw an exception. Developers shouldn’t simply rely on printouts so that they can visually inspect the result of calling the tested code. While visual inspection is better than nothing, it’s not nearly as useful as unit testing can be. This chapter shows several ways in which a lack of assertions shows up and provides strategies
b 449156 Ch01.qxd6/16/03
MOCK OBJECT VERSUS “IN CONTAINER” TESTING
There are two ways to approach testing your server-side objects. They can be isolated from the containers in which they are intended to run and tested separately to ensure that the objects do what is expected of them. The other way is to build a framework that works with the container to allow your objects to betested inside the container. The first approach, called Mock Object testing (or the Mock Objects Pattern), is very effective at isolating the test subject. There is significant burden, though, in building and maintaining the Mock Objects that simulate the configuration and container objects for the test subject. They have to be built and maintained in order for the testing to be effective. Eventhough there is virtually no complexity to the actual Mock Objects, there is a lot of complexity in maintaining the large number of Mock Objects required to simulate the container. Cactus takes the other approach and facilitates testing inside the container. Cactus gets between the test cases and the container and builds an environment for the test subject to be run in that uses thecontainer-provided objects instead of Mock Objects. Both approaches are helpful in stamping out bugs.
to migrate existing tests (visual or not) to solid unit tests that assert the contract implied in the API being tested. A quick word about the differences between JUnit and Cactus: JUnit tests run in the same JVM as the test subject whereas Cactus tests start in one JVM and are sent to the app server’s JVM tobe run. Cactus has a very clever means to do the sending to the remote machine. Just enough information is packaged so that the server side can find and execute the test. The package is sent via HTTP to one of the redirectors (ServletTestRedirector, FilterTestRedirector, or the JSPTestRedirector). The redirector then unpacks the info, finds the test class and method, and performs the test. Figure1.1 represents this process.
Client JVM beginXXX() serializeAndSend() endXXX() Cactus TestCase HTTP Request Cactus Redirector
Server JVM setUp() testXXX() tearDown()
Figure 1.1 Cactus and test methods.
b 449156 Ch01.qxd
Testing: Cactus and JUnit
Misunderstanding the distributed nature of Cactus can lead to frustration if you are an old hand...