I have a bunch of servlets running under the Tomcat servlet container. I would like to separate test code from production code, so I considered using a test framework. JUnit is nicely integrated into Eclipse, but I failed to make it run servlets using a running Tomcat server. Could you please recommend a unit testing framework that supports testing Tomcat servlets? Eclipse integration is nice but not necessary.
6 Answers
Check out ServletUnit, which is part of HttpUnit. In a nutshell, ServletUnit provides a library of mocks and utilities you can use in ordinary JUnit tests to mock out a servlet container and other servlet-related objects like request and response objects. The link above contains examples.
Okay. Ignoring the 'tomcat' bit and coding to the servlet, your best bet is to create mocks for the response and request objects, and then tell it what you expect out of it.
So for a standard empty doPost, and using EasyMock, you'll have
public void testPost() {
mockRequest = createMock(HttpServletRequest.class);
mockResponse = createMock(HttpServletResponse.class);
replay(mockRequest, mockResponse);
myServlet.doPost(mockRequest, mockResponse);
verify(mockRequest, mockResponse);
}
Then start adding code to the doPost. The mocks will fail because they have no expectations, and then you can set up the expectations from there.
Note that if you want to use EasyMock with classes, you'll have to use the EasyMock class extension library. But it'll work the same way from then on.
Separate the parts of that code that deal with HTTP requests and response from the parts that do business logic or data-base manipulation. In most cases this will produce a three tier architecture, with a data-layer (for the data-base/persistence), service-layer (for the business logic) and a presentation-layer (for the HTTP requests and responses).
- You can unit test the first two layers without any servlet stuff at all; it will be easier to test that way.
- You can test the presentation layer, as others suggest, using mock HTTP request and response objects.
- Finally, if you feel it really is necessary, you can do integration tests using a too such as HtmlUnit or JWebUnit .
For "in-container" testing, have a look at Cactus
If you want to be able to test without a running container you can either simulate its components with your own mockobjects (e.g. with EasyMock) or you could try MockRunner which has "pre-defined" Stubs for testing servlets, jdbc-connections etc.
Updated Feb 2018: OpenBrace Limited has closed down, and its ObMimic product is no longer supported.
If you want a newer alternative to ServletUnit for JUnit testing of Servlets, you might find my company's ObMimic library useful. It's available for free from the website's downloads page.
As with ServletUnit, it provides a library of classes that you can use in normal JUnit or TestNG tests outside of any servlet container to simulate the Servlet API.
Its Servlet API objects have no-argument constructors, are fully configurable and inspectable for all relevant Servlet API data and settings, and provide a complete simulation of all of the behaviour specified by the Servlet API's javadoc. To help with testing there's support for selective recording of Servlet API calls, control over any container-dependent behaviour, checks for any ambiguous calls (i.e. where the Servlet API behavour isn't fully defined), and an in-memory JNDI simulation for any servlet code that relies on JNDI lookups.
For full details, example code, "how to" guides, Javadoc etc, see the website.