
























|

The process is as follows for each XXX test method of your
TestYYY test class :
-
JUnit calls your the
TestYYY.runTest() method (inherited
from ServletTestCase ). This later looks for a
beginXXX(ServletTestRequest) method. If one is found,
it executes it. This is executed on the client side (i.e. not in a
server engine). The ServletTestRequest
parameter passed to the beginXXX() method is used
to set the HTTP headers, the HTTP parameters, ... that will be
sent in step 2 to the Redirector proxy.
-
The
TestYYY.runTest() method then opens an HTTP
connection to the Redirector proxy. All the parameters set up
in the beginXXX() method are put in the HTTP request
(HTTP headers, HTTP parameters, ...)
-
The Redirector proxy acts as a proxy for your
TestYYY
test class, but on the server side. It means that TestYYY
is instantiated twice : once on the client side and once on the
server side. The client side instance is used for executing the
beginXXX() and endXXX() methods (see
steps 1 and 8) and the server side instance is used for executing
the testXXX() methods (see step 4). The Redirector
proxy does the following :
-
creates an instance of
TestYYY using reflection. It
sets by reflection the J2EEUnit implicit objects (see the section
below on Servlet Redriector Proxy and JSP Redirector Proxy for a
list of available objects).
-
creates instances of J2EEUnit wrappers for some server objects
(
HttpServletRequest , ServletConfig ,
ServletContext , ...). This is to be able to
to override some methods in order to return simulated values.
For example, the J2EEUnit framework can simulate an URI (i.e.
act as if this URI was called instead of the Redirector proxy
URI). Thus, the getServerName() , getServerPort() ,
getRequestURI() , ... methods return values based
on the simulated URI (if there is any defined by the user).
-
creates an HTTP Session if the user has expressed the wish
(using the
ServletTestRequest.setAutomaticSession(boolean)
code in the beingXXX() method. By default a session
is always created) and it fills by reflection the
session implicit object.
-
The
TestYYY.setUp() , TestYYY.testXXX() and
tearDown() methods are executed (in that order). They
are called by the Redirector proxy using reflection.
-
Your
TestYYY.testXXX() method calls your server
side code, executing the test and using the JUnit asserts to assert
the result (assert() , assertEquals() ,
fail() , ...)
-
If the test fails, your
TestYYY.testXXX() methods
throws exceptions to the Redirector proxy.
-
If an exception has been raised, the Redirector proxy returns the
information about the exception (it's name, class, stack trace) back
to the client side. It will then be printed by JUnit in it's Test
Runner console.
-
If no exception occurred, the
TestYYY.runTest()
method looks for an endXXX(HttpURLConnection) method
and executes it if found. At this stage, you have the opportunity
to check returned HTTP headers, Cookies and the servlet output
stream in the endXXX() method, again using JUnit asserts
and helper utility classes provided by J2EEUnit (see the sample
application).
J2EEUnit provides 2 implementation for the Redirector Proxy :
-
A Servlet Redirector. This redirector is a servlet that
should be used for unit testing servlet methods. It provides the
following implicit objects :
request ,
response , session and config .
-
A JSP Redirector. This redirector is a JSP page that
should be used for unit testing server code that need access to
the following objects :
pageContext and
out . These objects are provided in addition to all the
objects provided by the Servlet Redirector. It can be useful for
testing simple JSP custom Tag libraries.
 |
Testing custom JSP Tag libraries is still in beta. I am still not sure
of the usefulness of this ... I think unit testing tag libraries is
much less relevant than doing functional tests, but this is an open
subject ...
|

The client side opens 2 HTTP connections to the Servlet redirector.
Once to execute the tests and retrieve the servlet output stream and
a second time to get the test result. This is to be able to get
the exception data (message, stack trace, ...) if the test failed.
The test results are stored in a servlet-context-wide scope variable
which is retrieved on the second HTTP connection.
|

The client side opens 2 HTTP connections. Once to the Redirector
JSP to execute the tests and retrieve the JSP output stream and
a second time to the Servlet Redirector to get the test result.
This is to be able to get the exception data (message,
stack trace, ...) if the test failed.
The test results are stored in a servlet-context-wide scope variable
which is retrieved on the second HTTP connection.
|
|
|
|
|