Testing the HTML Generation

The doGet method of our sample login servlet could also gain in testability if we were to use the Builder [9] design pattern instead of directly creating HTML code. More specifically, we would have to introduce an interface, PageBuilder, and a corresponding factory. The builder interface could look like this:

public Interface PageBuilder {
 void addTitle(String title);
 void addText(String text);
 void startForm(String name, String method, String action);
 void addInput(String type, String name, String value);
 void endForm();
 void createHtml(OutputStream stream);

The builder can be replaced by a MockPageBuilder in the usual way for testing purposes. In addition to better testability, this would ensure total independence of the page layout, just what we like to have for our unit tests. This friendly approach towards testing has little significance in the real world, because the servlet itself is seldomly used to create HTML today. The main reason is that the Model View Controller (MVC) approach, known from GUI development, has become popular in Web app development. The purpose of this pattern is to make the actual app objects (model) independent of their representation (view) and access logic (controller). MVC is described in many publications [Lewis95]. In Web apps, views are often programmed as Java Server Pages (JSPs), and controllers as servlets, and models as normal Java classes or specialized wrapper beans. One of the reasons for this division is that the layout of a Web page, represented in the JSPs, can potentially be defined and modified by nondevelopers.

Java Server Pages

As the name suggests, JSPs are nothing more than HTML pages using special tags to embed Java code or to access the attributes of Java beans. If we strictly follow the MVC division, then we will hardly find any Java code in a JSP that would have to be tested. The logic for the flow control dwells in the servlets, while the special logic resides in the models, where it can be tested. What really remains in the JSPs is code to access bean attributes, to pass through a loop, and to display/hide parts of pages. The very few things that could go wrong here are normally not tested in unit tests, but rather in functional tests. At that point, we can use HttpUnit or a similar tool to validate HTML pages.

Those who think they cannot do without unit tests for a JSP have to take the roundabout route over a Web server, and perhaps Cactus. An interesting attempt would be the integration of a JSP compiler (e.g., Jasper), which is integrated in Apache's servlet engine Tomcat [URL:Tomcat], into a dedicated JSP test framework. However, this idea has never been realized to my knowledge.

JSP Custom Tags

The small amount of Java code required in JSPs can be further reduced if we implement so-called JSP custom tags. These user-defined tags allow us to embed arbitrary functionality into a JSP, while maintaining the HTML or XML syntax, and without the slightest Java knowledge. User-defined tags are supplied to the app server in a tag library. Creating such a library is pure coding work. The classes and interfaces needed are available in the package javax.servlet.jsp.tagext. Creating unit tests for your own tags means you have to do some mocking for a few interfaces and classes. A detailed description of this approach would go beyond the scope of this tutorial; there are many sources, including Message 29405 at [URL:YahooXP], and the KaCoMa project [URL:KaCoMa], which is designed to be a tutorial for beginners of custom tag libraries and unit testing of corresponding software.


With Struts [URL:Struts], there exists a widely used Web app framework based on the Model 2 approach, which is a variation of the classic MVC paradigm. Struts provides its own controller component and integrates with other technologies to provide the model and the view. For the model, Struts can interact with any standard data access technology, including Enterprise Java Beans and JDBC. For the view, Struts works well with JSPs, XSLT, and other presentation systems. When using Struts some of the standard testing problems we discussed in this chapter are no longer an issue since we don't have to fuss around with the basic Servlet mechanism any longer. However, Struts is no test-first paradise either, which provoked the development of StrutsTestCase [URL:StrutsTest], an extension of junit.framework TestCase. [9]The description of this pattern—and others—is easier to understand in the work of Alpert et al. [98] than in the seminal work of Gamma et al. [95].