I have a Servlet-based application (OAuth implementation) which delegates some of the response rendering to JSP, as in the following example:
private void doLoginPage( AuthorizationSession authzSession, String errorMsg, HttpServletRequest request, HttpServletResponse response ) throws OAuthSystemException {
try {
response.setHeader( HTTP.CONTENT_TYPE, ContentType.create( "text/html", "utf-8" ).toString() );
request.getRequestDispatcher( "/WEB-INF/OAuthLogin.jsp" ).include( request, response );
} catch ( Throwable e ) {
throw new OAuthSystemException( "Error generating login page", e );
}
}
Here's the JSP file (simplified):
<%@ page contentType="text/html;charset=UTF-8" language="java" session="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="errorMsg" scope="request" class="java.lang.String"/>
<html>
<head>
<title>Sign In</title>
</head>
<body style="text-align: center;">
<h1>Sign In</h1>
<div style="border: 1px black;">
<c:if test="${!(empty errorMsg)}">
<p style="color:red;">${errorMsg}</p>
</c:if>
<form method="post" action="<c:url value="/authorize"/>">
<div><label for="email">Email:</label></div>
<div><input type="text" name="email" id="email"/></div>
<div><label for="password">Password:</label></div>
<div><input type="password" name="password" id="password"/></div>
<div><input type="submit" title="Sign In" /></div>
</form>
</div>
</body>
</html>
I've got my unit testing set up so that I can run server-based tests as unit tests, with injected mocks, using Jetty as an in-process server (OK, so it's not pure unit testing).
As part of my unit testing, I wrote a test to ensure that the page is being rendered when appropriate, and that it includes certain key properties (I'm using TestNG and Hamcrest):
@Test
public void testRequestGrantYieldsLoginPage() throws Exception {
HttpGet request = new HttpGet( String.format( "%s/authorize?client_id=%s&redirect_uri=%s&response_type=token",
serverConnector.getServerURL(),
"*******secret*****",
URLEncoder.encode( "*****secret*********", "UTF-8" )));
DefaultHttpClient httpClient = new SystemDefaultHttpClient();
HttpResponse response = httpClient.execute( request );
assertThat( response, is( notNullValue() ));
assertThat( response.getStatusLine().getStatusCode(), is( 200 ));
assertThat( response.getEntity().getContentType().toString(), containsString( "text/html" ));
String body = IOUtils.toString( response.getEntity().getContent() );
assertThat( body, allOf(
is( notNullValue()),
containsString( "value=\"gQwCAShitcuP-_2OY58lgw3YW0AfbLE8m62mrvXWvQbiDLJk9QnDTs7pc0HH\"" )
));
}
This works fine when I run my unit tests from my IDE (IntelliJ), but when I run them under Maven's Surefire, this particular test fails: the server thread throws an exception as follows:
org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application
This of course causes the client side of the test to fail, since it gets back an error response instead of the expected login page.
So what's different between the two testing environments, and how can I make this test work in both?