How to unit test a Servlet

A

andrewmcdonagh

Having been asked how to unit test a servlet without using a container,
so much lately, I thought an example here might help - certainly should
help if the search engines pick it up.

Regards

Andrew


The servlet to test...

package org.amd.sandbox;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {
public void doGet (HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
PrintWriter out = res.getWriter();

out.print("Hello, world!");
out.close();
}
}


The Unit Test....

package org.amd.sandbox;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletResponse;

import junit.framework.TestCase;

public class HelloServletTest extends TestCase {

public void testDoGetSaysHello() throws Exception {
StringWriter out = new StringWriter();

HttpServletResponse res = new MockResponse(out);
HelloServlet servlet = new HelloServlet();

servlet.doGet(null, res);

assertEquals("Hello, world!", out.toString());
}

}


Two helper classes......


Andrew


The servlet to test...

package org.amd.sandbox;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {
public void doGet (HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
PrintWriter out = res.getWriter();

out.print("Hello, world!");
out.close();
}
}


The Unit Test....

package org.amd.sandbox;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletResponse;

class MockResponse extends HttpServletResponseAdapter {

private StringWriter out;

public MockResponse(StringWriter stringWriter) {
out = stringWriter;
}

public PrintWriter getWriter() {
return new PrintWriter(out);
}

}



The following class was auto generated by Eclipse - Its purpose is to
provide a simple implementation of the HttpServletResponse interface
and its methods are purposely left as shown below. Its the purpose of
the deriving class MockResponse, above that over rides all methods
that are needed by the current unit test.

Obviously, the more correctly implemented methods required by further
unit tests, means extending the current MockResponse class.

package org.amd.sandbox;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;


public class HttpServletResponseAdapter implements HttpServletResponse
{


public void addCookie(Cookie arg0) {
throw new RuntimeException("HttpServletResponseAdapter.addCookie()
not yet implemented - faked for unit tests");
}

public boolean containsHeader(String arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.containsHeader() not yet
implemented - faked for unit tests");
}

public String encodeURL(String arg0) {
throw new RuntimeException("HttpServletResponseAdapter.encodeURL()
not yet implemented - faked for unit tests");
}

public String encodeRedirectURL(String arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.encodeRedirectURL() not
yet implemented - faked for unit tests");
}

public String encodeUrl(String arg0) {
throw new RuntimeException("HttpServletResponseAdapter.encodeUrl()
not yet implemented - faked for unit tests");
}
public String encodeRedirectUrl(String arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.encodeRedirectUrl() not
yet implemented - faked for unit tests");
}

public void sendError(int arg0, String arg1) throws IOException {
throw new RuntimeException("HttpServletResponseAdapter.sendError()
not yet implemented - faked for unit tests");
}

public void sendError(int arg0) throws IOException {
throw new RuntimeException("HttpServletResponseAdapter.sendError()
not yet implemented - faked for unit tests");
}

public void sendRedirect(String arg0) throws IOException {
throw new
RuntimeException("HttpServletResponseAdapter.sendRedirect() not yet
implemented - faked for unit tests");
}

public void setDateHeader(String arg0, long arg1) {
throw new
RuntimeException("HttpServletResponseAdapter.setDateHeader() not yet
implemented - faked for unit tests");
}
public void addDateHeader(String arg0, long arg1) {
throw new
RuntimeException("HttpServletResponseAdapter.addDateHeader() not yet
implemented - faked for unit tests");
}
public void setHeader(String arg0, String arg1) {
throw new RuntimeException("HttpServletResponseAdapter.setHeader()
not yet implemented - faked for unit tests");
}

public void addHeader(String arg0, String arg1) {
throw new RuntimeException("HttpServletResponseAdapter.addHeader()
not yet implemented - faked for unit tests");
}
public void setIntHeader(String arg0, int arg1) {
throw new
RuntimeException("HttpServletResponseAdapter.setIntHeader() not yet
implemented - faked for unit tests");
}

public void addIntHeader(String arg0, int arg1) {
throw new
RuntimeException("HttpServletResponseAdapter.addIntHeader() not yet
implemented - faked for unit tests");
}

public void setStatus(int arg0) {
throw new RuntimeException("HttpServletResponseAdapter.setStatus()
not yet implemented - faked for unit tests");
}

public void setStatus(int arg0, String arg1) {
throw new RuntimeException("HttpServletResponseAdapter.setStatus()
not yet implemented - faked for unit tests");
}
public String getCharacterEncoding() {
throw new
RuntimeException("HttpServletResponseAdapter.getCharacterEncoding() not
yet implemented - faked for unit tests");
}

public String getContentType() {
throw new
RuntimeException("HttpServletResponseAdapter.getContentType() not yet
implemented - faked for unit tests");
}


public ServletOutputStream getOutputStream() throws IOException {
throw new
RuntimeException("HttpServletResponseAdapter.getOutputStream() not yet
implemented - faked for unit tests");
}

public PrintWriter getWriter() throws IOException {
throw new RuntimeException("HttpServletResponseAdapter.getWriter()
not yet implemented - faked for unit tests");
}

public void setCharacterEncoding(String arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.setCharacterEncoding() not
yet implemented - faked for unit tests");
}

public void setContentLength(int arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.setContentLength() not yet
implemented - faked for unit tests");
}
public void setContentType(String arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.setContentType() not yet
implemented - faked for unit tests");
}
public void setBufferSize(int arg0) {
throw new
RuntimeException("HttpServletResponseAdapter.setBufferSize() not yet
implemented - faked for unit tests");
}
public int getBufferSize() {
throw new
RuntimeException("HttpServletResponseAdapter.getBufferSize() not yet
implemented - faked for unit tests");
}

public void flushBuffer() throws IOException {
throw new
RuntimeException("HttpServletResponseAdapter.flushBuffer() not yet
implemented - faked for unit tests");
}
public void resetBuffer() {
throw new
RuntimeException("HttpServletResponseAdapter.resetBuffer() not yet
implemented - faked for unit tests");
}

public boolean isCommitted() {
throw new
RuntimeException("HttpServletResponseAdapter.isCommitted() not yet
implemented - faked for unit tests");
}

public void reset() {
throw new RuntimeException("HttpServletResponseAdapter.reset() not
yet implemented - faked for unit tests");
}

public void setLocale(Locale arg0) {
throw new RuntimeException("HttpServletResponseAdapter.setLocale()
not yet implemented - faked for unit tests");
}

public Locale getLocale() {
throw new RuntimeException("HttpServletResponseAdapter.getLocale()
not yet implemented - faked for unit tests");
}

}
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

andrewmcdonagh said:
Having been asked how to unit test a servlet without using a container,
so much lately, I thought an example here might help - certainly should
help if the search engines pick it up.

It should be noted that this code does not implement the full
functionality of the container context, which imposes some restrictions
on what the servlet can do.

If it is in any way possible, then I will find a Tomcat on the
dev box and Cactus a better test, because it has the full
container environment.

Arne
 
A

andrewmcdonagh

functionality of the container context, which imposes some restrictions
on what the servlet can do.

If it is in any way possible, then I will find a Tomcat on the
dev box and Cactus a better test, because it has the full
container environment.

Arne


That's right - and its purposely that way, as its a its a unit test -
its testing the helloworld class I wrote - just the current behaviour
within my servlet - not how the container works.

The (preferably) automated integration and system tests do that job,

Andrew
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

andrewmcdonagh said:
That's right - and its purposely that way, as its a its a unit test -
its testing the helloworld class I wrote - just the current behaviour
within my servlet - not how the container works.

The (preferably) automated integration and system tests do that job,

I am not talking about testing the container.

But this way of unit testing assume certain things
about the implementation in the servlet.

If the implementation is changed (like caching
in session or application), then you need to
modify the unit test to supply more of the
container environment.

If you use a container and Cactus, then the unit test
can focus on the interface.

Arne
 
A

andrewmcdonagh

But this way of unit testing assume certain things
about the implementation in the servlet.

If the implementation is changed (like caching
in session or application), then you need to
modify the unit test to supply more of the
container environment.

If you use a container and Cactus, then the unit test
can focus on the interface.

Arne

If the behaviour of the servlet has changed then we need to change the
test to prove the new behaviour works.

If the behaviour has not changed, but the implementation has, then the
test rarely needs changing. Sometimes they may need extra test case
setups.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

andrewmcdonagh said:
If the behaviour of the servlet has changed then we need to change the
test to prove the new behaviour works.

If the behaviour has not changed, but the implementation has, then the
test rarely needs changing. Sometimes they may need extra test case
setups.

And in this case fixing a not complete mockup environment.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top