En esta entrada mostraré un pequeño ejemplo para utilizar al
servidor Jetty embebido durante las pruebas (con JUnit 5) para cuando
necesitemos un Stub de algún servicio fuera de nuestro alcance.
1. Las dependencias:
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.4.28.v20200408</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.0</version>
<scope>test</scope>
</dependency>
2. La clase para definir los handlers, lanzar y detener el servidor Jetty en las pruebas:
import java.net.URI;
import java.nio.file.Path;
import java.util.concurrent.ThreadLocalRandom;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.PathResource;
public class JettyStub {
private Server server;
public URI uri() throws Exception {
crearServer(ThreadLocalRandom.current().nextInt(10000, 20000));
server.setStopAtShutdown(true);
server.start();
return server.getURI();
}
public void stop() throws Exception {
server.stop();
}
private void crearServer(int port) throws Exception {
server = new Server(port);
// definir recursos desde el sistema de archivos
final var rh = new ResourceHandler();
rh.setDirectoriesListed(true);
rh.setBaseResource(new PathResource(
Path.of(System.getProperty("user.dir")).resolve("target/test-classes")));
// definir servlets
final var sh = new ServletHandler();
sh.addServletWithMapping(new ServletHolder(new HelloServlet()), "/hello/*");
// agregar los handlers
server.setHandler(new HandlerList(rh, sh));
}
}
en esta clase agregué un handler para contenido estático desde el sistema de archivos y un servlet que responde en el path /hello/*:
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 HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.getOutputStream().print("""
{"hola": "chao"}""");
}
}
el servlet responderá un JSON y en el contenido estático también existe un archivo llamado demo.json (carpeta resources de test) con el siguiente contenido:
{"a":"b","c":"d"}
3. Las pruebas son las siguientes:
public class StubJettyTest {
private static final JettyStub JS = new JettyStub();
/** uri en la que responde el server. */
private static URI uri;
@BeforeAll
public static void beforeAll() throws Exception {
uri = JS.uri();
}
@AfterAll
public static void afterAll() throws Exception {
JS.stop();
}
@Test
public void obtengoElContenidoEsperadoDesdeServlet() throws MalformedURLException {
WebClient client = new WebClient();
var json = client.getContent(uri.resolve("/hello").toURL());
assertEquals("""
{"hola": "chao"}""", json);
json = client.getContent(uri.resolve("/hello?a=b").toURL());
assertEquals("""
{"hola": "chao"}""", json);
}
@Test
public void obtengoElContenidoEsperadoDesdeArchivo() throws MalformedURLException {
WebClient client = new WebClient();
String json = client.getContent(uri.resolve("demo.json").toURL());
assertEquals("""
{"a":"b","c":"d"}""", json);
}
}
y eso es todo, de esta simple manera podemos tener los stubs de los servicios que necesitamos durante nuestras pruebas 😌.En Github está el ejemplo junto a otros.