Friday, November 13, 2009

Better approach to unit testing pages in web applications

It's common to see two approaches to unit testing pages in web applications: in-container (real container and browser) and out of container (mocked container and no browser). The former is good in that the tests can check the HTML DOM element and thus works with AJAX, but it is difficult to mock the services as the web application is running "on the other side". The latter is the opposite: Easy to mock the services but usually the tests can only check the internal state of the program, not the end HTML code.

In fact, a better approach is to combine them together: Run the application in the container and run the container in-process so that the test code can mock the services. This way you can control the right thing (user input on the web page and the data your pages get, from the services), and then observe the right thing (HTML DOM elements, possible manipulated by Javascript/AJAX). In order to run the container in-process, we can, eg, run an embedded Jetty. As it is run in the same process, the test code can access the servlet context and thus can get the opportunity to replace the services with mocks.

I've created a proof of concept library for unit testing Wicket pages. The mocking is done by using a chain of component injectors. The first one keeps a map of mock objects. The second one is the normal one to inject Spring beans. Usually the map in the first injector is empty so it has no practical effect in production. But your tests can put mock objects into there to perform mocking.

The library is released as open source software (LGPL). You're welcome to check it out at There is a step-by-step tutorial.

Finally, potentially this approach can be applied to other web frameworks like JSF, Tapestry and etc.