![]() | ![]() |
Apache > Jakarta > Cactus | Docs for: v1.7.2 | v1.7 Last update: November 26 2008 |
Mock Objects vs In-Container testing
This article was written about 2 years ago and is starting to
be a bit old. The general content is still valid but several
details are no longer true as the frameworks (be it Cactus or
the mock objects frameworks) have evolved since then.
Throughout this article, we'll use the abbreviations MO for Mock
Objects and IC for In-Container strategy.
MO and Server-side testsMO is a strategy to unit test java classes in general. As such it is also applicable to unit test server side code like Servlets, Filters, Taglibs, EJBs, ... See the original article "Endo-Testing: Unit Testing with Mock Objects" for full details on MO. As such it is a challenger to Cactus but we'll see in the rest of this article that it is in fact complementary rather than a replacement. The main goal of MO is to unit test a method in isolation of other domain objects. Thus, the MO approach is to fake domain objects by using simulated copies instead of the real objects (be careful MO does not implement any logic in its fake objects, that would be "stubbing". All behaviours of mock objects are controlled by the unit test itself). This enables to finely unit test the method with no environment "noise" and to concentrate on unit testing its logic. When applied to servlet testing, it means mock objects need to be provided for simulating the servlet container. In other words a mock implementation of the Servlet API need to be provided (of course only the Servlet API methods used in the classes under test need to be mocked and the approach described in the white paper is to start small and develop the mock implementations as they are needed - Note that mock objects can even be generated at build time or at run time with JDK 1.3 dynamic proxies, see resources-). Cactus' strategy on the other hand has been to rely on the real container to provide the implementation of the Servlet API. In the rest of this article, we'll discuss the pros and cons of each approach and draw a conclusion. Let's start first by an example to understand better what are MO. An exampleSimple test case using Cactus: [...] MyServlet myServlet = new MyServlet(); [...] public void beginXXX(WebRequest theRequest) { theRequest.addParameter("param1", "value1"); theRequest.addParameter("param2", "value2"); } public void testXXX() { myServlet.init(config); myServlet.myMethod(request, response); assertEquals("some value", session.getAttribute("some_name_set_in_mymethod")); } public void endXXX(WebResponse theResponse) { String result = theResponse.getText(); assertEquals("<html><head/><body>A GET request</body></html>", result); } Simple test case using Mock Objects: [...] MockHttpServletRequest myMockHttpRequest = new MockHttpServletRequest(); MockHttpServletResponse myMockHttpResponse = new MockHttpServletResponse(); MockServletConfig myMockServletConfig = new MockServletConfig(); MyServlet myServlet = new MyServlet(); [...] public void testXXX() { myMockHttpRequest.setupAddParameter("param1", "value1"); myMockHttpRequest.setupAddParameter("param2", "value2"); myMockHttpRequest.setExpectedAttribute("some_name_set_in_mymethod", "some value"); myMockHttpResponse.setExpectedOutput("<html><head/><body>A GET request</body></html>"); myServlet.init(myMockServletConfig); myServlet.myMethod(myMockHttpRequest, myMockHttpResponse); myMockHttpRequest.verify(); myMockHttpResponse.verify(); } Differences between MO and ICComparison of pros and cons of MO versus IC.
This table is not meant to be comprehensive in
term of benefits/inconvenients of using MO. It is more focused on
pros and cons of MO when used for unit testing server side code (i.e.
what Cactus is focusing on).
A '+' indicates a positive point.For example
a '+' in the MO column shows that it has an advantage over IC.
ConclusionMock Objects are a very interesting way of doing unit testing which could bridge the gap between standard java class unit testing and server-side testing of container components. The biggest difference between the way Cactus currently works and Mock Objects is that Cactus tests tend to be more coarse-grained and they also ensure that developed code will run in the container. On the other hand, Mock Objects are more satisfactory intellectually because they are not limited to servlet unit testing but cover the whole spectrum of code. We believe the graininess of Cactus tests is just correct. Having fine-grained tests is nice but it is also a lot of effort. It seems Cactus tests are a middle ground where you can still do unit tests fine enough and at the same time it gives you *enough* confidence that your tests will run fine when deployed. Also, as described on the Cactus' goals page, we think that a framework like Cactus will be more and more useful as we use more and more components in the future because it will provide the needed confidence that the code will run ok in the container. We also believe that writing correctly MO tests is a difficult process that need some training. MO are good because they let you write better code but it is more difficult to understand than Cactus tests. Finally, we believe that MO and Cactus are complementary in 2 areas:
We would very much like to have your feedback on MO vs IC. Please post your feedback on the Cactus mailing list. Thanks a lot. Resources on MOSome links:
|