When to use?
Your test case class should extend
ServletTestCase
whenever you are unit testing:
- Servlets,
- Any java code that uses Servlet API objects (
HttpServletRequest
, ...)
Provided Implicit Objects
Cactus automatically initializes the implicit objects for you and they are made available to your
setUp()
,testXXX()
andtearDown()
methods as instance variables of theServletTestCase
class (and thus as instance variables of your test case class as it extendsServletTestCase
).You may ask yourself how Cactus initializes these objects. The mechanism is described in the How it works guide.The provided implicit objects are:
request
Instance variable name request
Class name org.apache.cactus.server.HttpServletRequestWrapper
, which inherits fromjavax.servlet.http.HttpServletRequest
Cactus wraps methods of the original HTTP request in order to return the HTTP related parameters set up in the
beginXXX()
method. Thus, you will be able to pass this request object to your code to test and set the needed parameter in thebeginXXX()
method.For example, if your code under test calls
getCookies()
on the request object that you have passed to it, it will return the cookies that you have added to the HTTP request inbeginXXX()
by calling theWebRequest.addCookie()
method.See the javadoc for the
org.apache.cactus.WebRequest
andorg.apache.cactus.server.HttpServletRequestWrapper
classes for all details. You should also look at the samples provided in the Cactus distribution.Additional methods
Cactus provides some additional methods to ease writing tests (see the javadoc for full details). These methods are provided because it is not easy (if not downright impossible in some cases) to simulate them with real configuration data:
setRemoteIPAddress()
: sets the remote IP address that will be returned bygetRemoteIPAddress()
,setRemoteHostName()
: sets the remote Host name that will be returned bygetRemoteHostName()
,setRemoteUser()
: sets the remote user name that will be returned bygetRemoteUser()
.response
Instance variable name response
Class name javax.servlet.http.HttpServletResponse
Cactus does not wrap the response.config
Instance variable name config
Class name org.apache.cactus.server.ServletConfigWrapper
, which inherits fromjavax.servlet.ServletConfig
Cactus wraps the original Servlet Config for two reasons:
- In order to provide additional methods. For example, it is possible to initialise parameters without setting them in
web.xml
, etc...,- So that it can return a wrapped Servlet Context instead of the original one. This is because the Servlet Context is used to perform forwards and includes and we need to pass to these methods the original request and response. As we have wrapped the request, we need to wrap the Servlet Context to pass the original request (and not the wrapped one).
The
config
implicit object will contain all initialisation parameters defined inweb.xml
under the Servlet Redirector servlet definition.See the javadoc for the
org.apache.cactus.server.ServletConfigWrapper
class for all details. You should also look at the samples provided in the Cactus distribution.Additional methods
Additional methods provided:
setInitParameter()
: sets an initialisation parameter (as if it has been defined in theweb.xml
file),setServletName()
: sets the Servlet name that will be returned bygetServletName()
(if not set, the Cactus Servlet redirector name will be returned).ServletContextWrapper
This is not an implicit object per see (as it is not accessible as an instance variable). It is available by calling
config.getServletContext()
.However, Cactus wraps the
ServletContext
in aServletContextWrapper
in order to take into account simulated URLs and provide additional methods to help write tests.See the javadoc for the
org.apache.cactus.server.ServletContextWrapper
class for all details. You should also look at the samples provided in the Cactus distribution.Additional methods
Additional methods provided:
getLogs()
: returns the text that has been logged by calls toServletContext.log()
methods. This is a helper method that makes it easy to assert what is logged.session
Instance variable name session
Class name javax.servlet.http.HttpSession
Cactus does not wrap the response.By default, Cactus always creates an HTRP session for your test case. It is possible to tell it not to do so by calling the
WebRequest.setAutomaticSession(false)
method (it istrue
by default). This could be useful for cases where your code under test verifies branches when "request.getSession(false)
" isnull
.
Tips and Tricks
Parameter initialisation
If your code under test make use of any of the servlet methods inherited from
javax.servlet.GenericServlet
(these are thelog()
,getServletConfig()
, ... methods), then you need to call theinit(ServletConfig)
method of your servlet to initialise its internalServletConfig
object.For example:
public void testXXX() { MyServletToTest servlet = new MyServletToTest(); servlet.init(config); // Call a method to test that uses a method inherited from Generic Servlet servlet.someMethodToTest(); [...] }See the samples provided as part of the Cactus distribution.
Sample
This is a very basic sample intended to give you a flavour of Servlet unit testing. Check the distribution samples for extensive examples.
This example is for Cactus 1.2 and above as it uses the newWebRequest
andWebResponse
objects.public void beginXXX(WebRequest theRequest) { // Set up HTTP related parameters theRequest.setURL("jakarta.apache.org", "/mywebapp", "/test/test.jsp", null, null); theRequest.addCookie("cookiename", "cookievalue"); } public void testXXX() { MyServletToTest servlet = new MyServletToTest(); servlet.init(config); // Call method to test servlet.methodToTest(); // Perform some server side asserts assertEquals("someValue", session.getAttribute("someAttribute")); assertEquals("jakarta.apache.org", request.getServerName()); } public void endXXX(WebResponse theResponse) { // Asserts the returned HTTP response Cookie cookie = theResponse.getCookie("someCookie"); assertEquals("someValue2", cookie.getValue()); assertEquals("some content here", theResponse.getText()); }