gpt4 book ai didi

java - 向新创建的 jetty 服务器发送请求以进行测试

转载 作者:行者123 更新时间:2023-11-30 06:22:35 26 4
gpt4 key购买 nike

我正在编写集成 JUnit 测试。我的任务是测试本地服务器的响应是否正确。上述服务器将要分析的页面地址作为 GET 参数(例如:localhost:8000/test?url=http://www.example.com)。

为了避免依赖 www.example.com,我想为这个特定的测试开始我自己的 jetty 服务器,它始终提供相同的内容。

private static class MockPageHandler extends AbstractHandler {
public void handle(String target,Request baseRequest, HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html; charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
final String responseString = loadResource("index.html");
response.getWriter().write(responseString);
baseRequest.setHandled(true);

}
}

public void test() throws Exception {
final int PORT = 8080;
final Server server = new Server(PORT);
server.setHandler(new MockPageHandler());
server.start();

final ContentResponse response =
client.newRequest("http://localhost:8000/test?url=http://localhost:8080").send();

/* some assertions. */

server.stop();
server.join();
}

每次执行此测试时,MockPageHandler 中的handle 方法都不会被调用。为什么这行不通,您有什么建议吗?

附言当我删除 server.stop() 并在浏览器中键入 http://localhost:8080 时,会显示正确的页面。

最佳答案

快速回答:

删除 server.join() 行。该行使 junit 线程等待,直到服务器线程停止。单元测试不需要它。

长答案:

我们(jetty 开发人员)在使用带有 junit 的 jetty 嵌入式服务器方面学到了什么。

如果您有 1 种测试方法,或者某些要求服务器在测试方法之间处于原始状态,则使用 @Before@After 注释来启动和停止服务器。

示例@Before/@After (Jetty 9.x):

public class MyTest
{
private Server server;
private URI serverUri;

@Before
public void startServer() throws Exception
{
this.server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(0); // let connector pick an unused port #
server.addConnector(connector);

ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);

// Serve capture servlet
context.addServlet(new ServletHolder(new MyServlet()),"/my/*");

// Start Server
server.start();

String host = connector.getHost();
if (host == null)
{
host = "localhost";
}
int port = connector.getLocalPort();
this.serverUri = new URI(String.format("http://%s:%d/",host,port));
}

@After
public void stopServer()
{
try
{
server.stop();
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
}

@Test
public void testMe()
{
// Issue request to server
URI requestUri = serverUri.resolve("/my/test");
// assert the response
}
}

此技术使服务器在端口 0 上启动,这是一个神奇的数字,告诉底层堆栈选择一个空端口并开始监听。然后,测试用例询问服务器它正在监听的端口号,并构建适合此测试运行的 serverUri 字段。

此技术效果很好,但是,它会针对每种方法启动/停止服务器。

进入,更好的技术,使用@BeforeClass@AfterClass 注释为整个测试类启动/停止一次服务器,运行里面的所有方法针对此启动服务器的测试类。

示例@BeforeClass/@AfterClass (Jetty 9.x):

public class MyTest
{
private static Server server;
private static URI serverUri;

@BeforeClass
public static void startServer() throws Exception
{
server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(0); // let connector pick an unused port #
server.addConnector(connector);

ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
server.setHandler(context);

// Serve capture servlet
context.addServlet(new ServletHolder(new MyServlet()),"/my/*");

// Start Server
server.start();

String host = connector.getHost();
if (host == null)
{
host = "localhost";
}
int port = connector.getLocalPort();
serverUri = new URI(String.format("http://%s:%d/",host,port));
}

@AfterClass
public static void stopServer()
{
try
{
server.stop();
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
}

@Test
public void testMe()
{
// Issue request to server
URI requestUri = serverUri.resolve("/my/test");
// assert the response
}
}

看起来没什么不同?是的,变化是微妙的。 @Before 变成了 @BeforeClass@After 变成了 @AfterClass。启动/停止方法现在是静态的。 serverserverUri 字段现在是静态的。

这种技术用于我们有许多访问同一服务器的测试方法,并且这些请求不会改变服务器中的状态。这通过简单地不在每个测试方法之间重新创建服务器来加速测试用例的执行。

关于java - 向新创建的 jetty 服务器发送请求以进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19113359/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com