Servlets zu schreiben gehört nun nicht gerade zu meinem Alltagsaufgaben, aber für ein JSON-Endpoint muss ein Servlet nun doch mit ins Boot. (REST-API geht leider nicht.) Einen Test dafür zu schreiben finde ich selbstverständlich, da ich geil auf grüne Balken bin (nein, nicht die Download-Balken). Es kommen für Servlet-Tests unterschiedliche Ansätze in Betracht, die sich grundsätzlich in 2 Gruppen einteilen lassen:
- Tests mit einem echten (embedded) Servlet-Container
- Mock-Tests
Dass ich ein Jetty-Fan bin ist vielleicht schon in früheren Posts rübergekommen, aber hier lasse ich meinen Lieblingsserver links liegen und gehe auf die Mock-Tests. Gut funktioniert für mich spring-test. Ein Beispiel.
Das Servlet:
package com.tutego.traida.server.service.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Raplet extends HttpServlet
{
private static final long serialVersionUID = 6942655630840028053L;
@Override
protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException,
IOException
{
resp.getWriter().print( "hello " + req.getParameter( "name" ) );
}
}
Der Test:
package com.tutego.traida.server.service.servlet;
import javax.servlet.ServletException;
import org.junit.*;
import static org.junit.Assert.*;
import org.springframework.mock.web.*;
public class RapletTest
{
private Raplet servlet = new Raplet();
private MockHttpServletRequest request;
private MockHttpServletResponse response;
@Before
public void before() throws ServletException
{
servlet.init( new MockServletConfig() );
this.servlet = new Raplet();
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
}
@Test
public void doGetTest() throws Exception
{
request.setParameter( "name", "tutego" );
servlet.doGet( request, response );
assertEquals( "hello tutego", response.getContentAsString() );
}
}
Einfacher geht’s nun wirklich nicht mehr.
Zum Ablaufen des Tests packe in den Klassenpfad:
- http://grepcode.com/snapshot/repo1.maven.org/maven2/org.springframework/spring-test/3.0.2.RELEASE
- http://grepcode.com/snapshot/repo1.maven.org/maven2/org.springframework/spring-core/3.0.2.RELEASE
Zwar bin ich kein Spring Fan Boy, aber mit 2 Archivdateien brennt die Jar-Hölle nicht so heiß (die Abhängigkeiten sind übertrieben).
Hallo,
vielen Dank für die Starthilfe, das funktioniert wirklich prima!
Hast Du auch etwas Ähnliches für Jetty und vielleicht auch Erfahrung mit mit cactus und Tomcat 6 ?
Danke, Dirk
Wie meinst du? Der Test braucht ja eben keinen Servlet-Container, also weder Jetty noch Tomcat. Oder meinst du für in-container-tests? Cactus ist quasi tot…
Das Feld servlet wird zweimal gesetzt, was wahrscheinlich nicht gewollt ist.
public class RapletTest
{
private Raplet servlet = new Raplet();
@Before
public void before() throws ServletException
{
servlet.init( new MockServletConfig() );
this.servlet = new Raplet();
}
}