public void doFilter(ServletRequest req, ServletResponse
res)
throws IOException, ServletException {
this.wasInvoked = true;
}
public void setExpectedInvocation(boolean shouldBeInvoked)
{
this.shouldBeInvoked = shouldBeInvoked;
}
public void verify( ) {
Assert.assertTrue("Expected MockFilterChain to be
invoked.",
this.wasInvoked);
} else {
Assert.assertTrue("Expected MockFilterChain filter
not to be invoked.",
!this.wasInvoked);
}
}
}
7.11.4 See Also
Recipe 7.12 describes how to write a secure Cactus test. For more information on Mock Objects, see Chapter 6.
7.12 Securing Cactus Tests
7.12.1 Problem
You want to test a servlet that depends on an authenticated user.
7.12.2 Solution
Configure your web application to handle BASIC authentication and use Cactus to automatically create an authenticated user.
7.12.3 Discussion
Testing server-side code is challenging by itself. Throw in server-side code that relies on an
authenticated user, and the challenge grows. Cactus provides a way to test server-side code that relies on an authenticated user—by creating a user for you.[10]
[10] Cactus 1.4 only supports BASIC authentication.
If your servlet or filter uses the following methods then you need Cactus to create an authenticated user:
•
HttpServletRequest.getRemoteUser( )
•HttpServletRequest.getUserPrincipal( )
•HttpServletRequest.isUserInRole(String)
If your web application requires an authenticated user, your web application must be secured. In the deployment descriptor, you must declare the URL patterns to secure and which logical roles are allowed. Example 7-15 shows how this is done.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<!-- other elements left out for brevity -->
<!-- URL pattern not secured -->
<filter>
<filter-name>FilterRedirector</filter-name>
<filter-class>
org.apache.cactus.server.FilterTestRedirector
</filter-class>
</filter>
<!-- URL pattern secured -->
<filter>
<filter-name>SecureFilterRedirector</filter-name>
<filter-class>
org.apache.cactus.server.FilterTestRedirector
</filter-class>
</filter>
<filter-mapping>
<filter-name>SecureFilterRedirector</filter-name>
<url-pattern>/SecureFilterRedirector</url-pattern>
</filter-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>SecurityRestriction</web-resource-
name>
<url-pattern>/SecureFilterRedirector</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>filterTest</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
<security-role>
<role-name>filterTest</role-name>
</security-role>
</web-app>
The example above can be applied to any URL pattern, not just filters. For instance, if you want to secure access to a servlet or JSP, simply add more
url-pattern
elements. The role name is a logical role that is mapped to one or more users. An underlying authorization mechanism defines how role names are mapped. Tomcat, by default, uses the TOMCAT_HOME/conf/tomcat-users.xml file to define users and their roles. This is not a very strong authentication and authorization mechanism but does provide a convenient and easy means to run our tests. Here's an example showing how to add a new user and role to the tomcat-users.xml file:<tomcat-users>
<user name="javaxp" password="secret" roles="manager"/>
<user name="coyner_b" password="secret" roles="filterTest"/>
</tomcat-users>
Notice that the
filterTest
role matches the role name in the deployment descriptor. Example 7- 16 shows how to set up a test method to provide an authenticated user. ThebeginAuthenticatedUser(WebRequest)
method is accompanied by a test method calledtestAuthenticatedUser( )
—not shown here. TheWebRequest
object allows for the redirector to be specified before executing the server side test. Recall that Cactus uses acactus.properties file to set up redirectors for each Cactus test case. The values in the properties file are simply the URL patterns defined in the deployment descriptor. Thus, setting the redirector name programmatically simply changes the URL pattern. This provides ultimate flexibility because multiple test methods can be tested using a secured or nonsecured URL, where a secured URL requires an authenticated user.
Example 7-16. Setting up an authenticated user
public void beginAuthenticatedUser(WebRequest webRequest) {
webRequest.setRedirectorName("SecureFilterRedirector");
webRequest.setAuthentication(
new BasicAuthentication("coyner_b", "secret"));
}
7.12.4 See Also
Recipe 7.11 shows how to test servlet filters.
7.13 Using HttpUnit to Perform Complex Assertions
7.13.1 Problem
You want to use HttpUnit to perform complex assertions on the returned result.
7.13.2 Solution
Implement an
endXXX(com.meterware.httpunit.WebResponse)
method for a giventestXXX( )
method.7.13.3 Discussion
Cactus provides support for two
endXXX(WebResponse)
signatures. You, as the test writer, need to choose one of the method signatures. Cactus ensures that the correct method is invoked.// write this method for the standard Cactus response
public void endXXX(org.apache.cactus.WebResponse) {
// insert simple assertions
}
// or write this method to use HttpUnit
public void endXXX(com.meterware.httpunit.WebResponse) {
// insert complex assertions
}
These methods are executed on the client side JVM after the corresponding server side
testXXX(
)
method completes without throwing an exception.7.13.4 See Also
For more information on how to use HttpUnit to perform complex assertions, see Chapter 5.
7.14 Testing the Output of a JSP
7.14.1 Problem
You want to test the output of a JSP.
7.14.2 Solution
Write a
ServletTestCase
that sets up any information the JSP needs to execute and use aRequestDispatcher
to forward to the JSP page. The client sideendXXX(WebResponse)
method can then be used to perform assertions on the content of the JSP, which may be XML, HTML, or any other format that you expect.7.14.3 Discussion
Testing the output, or result, of a JSP is done using the client side
endXXX(WebResponse)
method. Example 7-17 shows how to write this test. The first step in writing a test like this is to write aServletTestCase
that sets up any information the JSP needs to generate the content. For example, the JSP may expect a particular object to be in theHttpSession
. This information might be retrieved though JDBC or an EJB. If the JSP does not rely on an object retrieved from an external source, or that external source is easily mocked, then Cactus is probably overkill.Example 7-17. Testing the result of a JSP