usar sirve servlet que para funciona example estructura ejemplo como java unit-testing servlets

sirve - Unidad de prueba de Java Servlet



servlet java ejemplo (7)

¿Llamas manualmente a los métodos doPost y doGet en las pruebas unitarias? De ser así, puede anular los métodos HttpServletRequest para proporcionar objetos simulados.

myServlet.doGet(new HttpServletRequestWrapper() { public HttpSession getSession() { return mockSession; } ... }

El HttpServletRequestWrapper es una clase de conveniencia Java. Le sugiero que cree un método de utilidad en las pruebas de su unidad para crear las solicitudes http simuladas:

public void testSomething() { myServlet.doGet(createMockRequest(), createMockResponse()); } protected HttpServletRequest createMockRequest() { HttpServletRequest request = new HttpServletRequestWrapper() { //overrided methods } }

Es incluso mejor poner los métodos de creación de prueba en una superclase de servlet base y hacer que todas las pruebas de unidad de servlets se extiendan.

Me gustaría saber cuál sería la mejor manera de hacer pruebas unitarias de un servlet.

Probar los métodos internos no es un problema siempre que no se refieran al contexto del servlet, ¿pero qué hay de probar los métodos doGet / doPost así como también el método interno que se refiere al contexto o hace uso de los parámetros de la sesión?

¿Hay alguna manera de hacerlo simplemente utilizando herramientas clásicas como JUnit o, preferiblemente, TestNG? ¿Debo integrar un servidor Tomcat o algo así?


Actualizado en febrero de 2018: OpenBrace Limited se ha cerrado y su producto ObMimic ya no es compatible.

Otra solución es usar mi biblioteca ObMimic , que está específicamente diseñada para pruebas unitarias de servlets. Proporciona implementaciones completas de Java simple de todas las clases de API de Servlet, y puede configurarlas e inspeccionarlas según sea necesario para sus pruebas.

De hecho, puede usarlo para llamar directamente a los métodos doGet / doPost de las pruebas JUnit o TestNG, y para probar cualquier método interno, incluso si se refieren a ServletContext o usan parámetros de sesión (o cualquier otra característica de API de Servlet).

Esto no necesita un contenedor externo o incrustado, no lo limita a pruebas de "integración" basadas en HTTP más amplias y, a diferencia de los simulacros de propósito general, tiene el comportamiento completo de API de Servlet "integrado", por lo que sus pruebas pueden ser " estado basado en "en lugar de" interacción "(p. ej., sus pruebas no tienen que depender de la secuencia precisa de las llamadas a la API de Servlet realizadas por su código, ni de sus propias expectativas sobre cómo responderá la API de Servlet a cada llamada) .

Hay un ejemplo simple en mi respuesta a Cómo probar mi servlet usando JUnit . Para obtener todos los detalles y una descarga gratuita, visite el sitio web ObMimic .


Esta implementación de una prueba JUnit para el método servlet doPost () se basa solo en la biblioteca Mockito para simular instancias de HttpRequest , HttpResponse , HttpSession , ServletResponse y ServletResponse . Reemplace las claves de parámetros y la instancia de JavaBean por las que corresponden a los valores a los que se hace referencia en el archivo JSP asociado desde el que se llama a doPost ().

Dependencia Mockito Maven:

<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> </dependency>

Prueba JUnit:

import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.*; /** * Unit tests for the {@code StockSearchServlet} class. * @author Bob Basmaji */ public class StockSearchServletTest extends HttpServlet { // private fields of this class private static HttpServletRequest request; private static HttpServletResponse response; private static StockSearchServlet servlet; private static final String SYMBOL_PARAMETER_KEY = "symbol"; private static final String STARTRANGE_PARAMETER_KEY = "startRange"; private static final String ENDRANGE_PARAMETER_KEY = "endRange"; private static final String INTERVAL_PARAMETER_KEY = "interval"; private static final String SERVICETYPE_PARAMETER_KEY = "serviceType"; /** * Sets up the logic common to each test in this class */ @Before public final void setUp() { request = mock(HttpServletRequest.class); response = mock(HttpServletResponse.class); when(request.getParameter("symbol")) .thenReturn("AAPL"); when(request.getParameter("startRange")) .thenReturn("2016-04-23 00:00:00"); when(request.getParameter("endRange")) .thenReturn("2016-07-23 00:00:00"); when(request.getParameter("interval")) .thenReturn("DAY"); when(request.getParameter("serviceType")) .thenReturn("WEB"); String symbol = request.getParameter(SYMBOL_PARAMETER_KEY); String startRange = request.getParameter(STARTRANGE_PARAMETER_KEY); String endRange = request.getParameter(ENDRANGE_PARAMETER_KEY); String interval = request.getParameter(INTERVAL_PARAMETER_KEY); String serviceType = request.getParameter(SERVICETYPE_PARAMETER_KEY); HttpSession session = mock(HttpSession.class); when(request.getSession()).thenReturn(session); final ServletContext servletContext = mock(ServletContext.class); RequestDispatcher dispatcher = mock(RequestDispatcher.class); when(servletContext.getRequestDispatcher("/stocksearchResults.jsp")).thenReturn(dispatcher); servlet = new StockSearchServlet() { public ServletContext getServletContext() { return servletContext; // return the mock } }; StockSearchBean search = new StockSearchBean(symbol, startRange, endRange, interval); try { switch (serviceType) { case ("BASIC"): search.processData(ServiceType.BASIC); break; case ("DATABASE"): search.processData(ServiceType.DATABASE); break; case ("WEB"): search.processData(ServiceType.WEB); break; default: search.processData(ServiceType.WEB); } } catch (StockServiceException e) { throw new RuntimeException(e.getMessage()); } session.setAttribute("search", search); } /** * Verifies that the doPost method throws an exception when passed null arguments * @throws ServletException * @throws IOException */ @Test(expected = NullPointerException.class) public final void testDoPostPositive() throws ServletException, IOException { servlet.doPost(null, null); } /** * Verifies that the doPost method runs without exception * @throws ServletException * @throws IOException */ @Test public final void testDoPostNegative() throws ServletException, IOException { boolean throwsException = false; try { servlet.doPost(request, response); } catch (Exception e) { throwsException = true; } assertFalse("doPost throws an exception", throwsException); } }


La mayoría de las veces pruebo Servlets y JSP a través de ''Pruebas de Integración'' en lugar de Pruebas Unitarias puras. Hay una gran cantidad de complementos para JUnit / TestNG disponibles, que incluyen:

  • HttpUnit (el nivel más antiguo y mejor conocido, muy bajo que puede ser bueno o malo dependiendo de sus necesidades)
  • HtmlUnit (nivel superior a HttpUnit, que es mejor para muchos proyectos)
  • JWebUnit (se sienta encima de otras herramientas de prueba e intenta simplificarlas, la que yo prefiero)
  • WatiJ y Selenium (use su navegador para hacer las pruebas, que es más pesado pero realista)

Esta es una prueba JWebUnit para un servlet de procesamiento de pedidos simple que procesa la entrada desde el formulario ''orderEntry.html''. Espera una identificación de cliente, un nombre de cliente y uno o más artículos de pedido:

public class OrdersPageTest { private static final String WEBSITE_URL = "http://localhost:8080/demo1"; @Before public void start() { webTester = new WebTester(); webTester.setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_HTMLUNIT); webTester.getTestContext().setBaseUrl(WEBSITE_URL); } @Test public void sanity() throws Exception { webTester.beginAt("/orderEntry.html"); webTester.assertTitleEquals("Order Entry Form"); } @Test public void idIsRequired() throws Exception { webTester.beginAt("/orderEntry.html"); webTester.submit(); webTester.assertTextPresent("ID Missing!"); } @Test public void nameIsRequired() throws Exception { webTester.beginAt("/orderEntry.html"); webTester.setTextField("id","AB12"); webTester.submit(); webTester.assertTextPresent("Name Missing!"); } @Test public void validOrderSucceeds() throws Exception { webTester.beginAt("/orderEntry.html"); webTester.setTextField("id","AB12"); webTester.setTextField("name","Joe Bloggs"); //fill in order line one webTester.setTextField("lineOneItemNumber", "AA"); webTester.setTextField("lineOneQuantity", "12"); webTester.setTextField("lineOneUnitPrice", "3.4"); //fill in order line two webTester.setTextField("lineTwoItemNumber", "BB"); webTester.setTextField("lineTwoQuantity", "14"); webTester.setTextField("lineTwoUnitPrice", "5.6"); webTester.submit(); webTester.assertTextPresent("Total: 119.20"); } private WebTester webTester; }


Miré las respuestas publicadas y pensé que publicaría una solución más completa que realmente demuestra cómo hacer las pruebas utilizando GlassFish incrustado y su plugin Apache Maven.

Escribí el proceso completo en mi blog Usando GlassFish 3.1.1 Embebido con JUnit 4.x y HtmlUnit 2.x y coloqué el proyecto completo para descargar en Bitbucket aquí: image-servlet

Estaba viendo otra publicación en un servlet de imagen para etiquetas JSP / JSF justo antes de ver esta pregunta. Así que combiné la solución que utilicé en la otra publicación con una versión de prueba completa para esta publicación.

Cómo probar

Apache Maven tiene un ciclo de vida bien definido que incluye test . Usaré esto junto con otro ciclo de vida llamado integration-test para implementar mi solución.

  1. Deshabilite la prueba de unidad de ciclo de vida estándar en el plugin surefire.
  2. Agregar integration-test como parte de las ejecuciones del plugin surefire
  3. Agregue el plugin GlassFish Maven al POM.
  4. Configure GlassFish para que se ejecute durante el ciclo de vida de la integration-test .
  5. Ejecutar pruebas unitarias (pruebas de integración).

Plugin GlassFish

Agregue este complemento como parte de la <build> .

<plugin> <groupId>org.glassfish</groupId> <artifactId>maven-embedded-glassfish-plugin</artifactId> <version>3.1.1</version> <configuration> <!-- This sets the path to use the war file we have built in the target directory --> <app>target/${project.build.finalName}</app> <port>8080</port> <!-- This sets the context root, e.g. http://localhost:8080/test/ --> <contextRoot>test</contextRoot> <!-- This deletes the temporary files during GlassFish shutdown. --> <autoDelete>true</autoDelete> </configuration> <executions> <execution> <id>start</id> <!-- We implement the integration testing by setting up our GlassFish instance to start and deploy our application. --> <phase>pre-integration-test</phase> <goals> <goal>start</goal> <goal>deploy</goal> </goals> </execution> <execution> <id>stop</id> <!-- After integration testing we undeploy the application and shutdown GlassFish gracefully. --> <phase>post-integration-test</phase> <goals> <goal>undeploy</goal> <goal>stop</goal> </goals> </execution> </executions> </plugin>

Plugin Surefire

Agregue / modifique el complemento como parte de <build> .

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.12.4</version> <!-- We are skipping the default test lifecycle and will test later during integration-test --> <configuration> <skip>true</skip> </configuration> <executions> <execution> <phase>integration-test</phase> <goals> <!-- During the integration test we will execute surefire:test --> <goal>test</goal> </goals> <configuration> <!-- This enables the tests which were disabled previously. --> <skip>false</skip> </configuration> </execution> </executions> </plugin>

HTMLUnit

Agregue pruebas de integración como en el siguiente ejemplo.

@Test public void badRequest() throws IOException { webClient.getOptions().setThrowExceptionOnFailingStatusCode(false); webClient.getOptions().setPrintContentOnFailingStatusCode(false); final HtmlPage page = webClient.getPage("http://localhost:8080/test/images/"); final WebResponse response = page.getWebResponse(); assertEquals(400, response.getStatusCode()); assertEquals("An image name is required.", response.getStatusMessage()); webClient.getOptions().setThrowExceptionOnFailingStatusCode(true); webClient.getOptions().setPrintContentOnFailingStatusCode(true); webClient.closeAllWindows(); }

Escribí el proceso completo en mi blog Usando GlassFish 3.1.1 Embebido con JUnit 4.x y HtmlUnit 2.x y coloqué el proyecto completo para descargar en Bitbucket aquí: image-servlet

Si tiene alguna pregunta, por favor deje un comentario. Creo que este es un ejemplo completo para usar como base de cualquier prueba que esté planificando para servlets.


Mockrunner ( http://mockrunner.sourceforge.net/index.html ) puede hacer esto. Proporciona un contenedor simulado J2EE que se puede usar para probar Servlets. También se puede usar para probar unidades de otro código del lado del servidor como EJB, JDBC, JMS, Struts. Solo he usado las capacidades JDBC y EJB yo mismo.


Pruebe HttpUnit , aunque es probable que termine escribiendo pruebas automatizadas que son más ''pruebas de integración'' (de un módulo) que ''pruebas unitarias'' (de una sola clase).