Spark Web 框架单元测试
Spark web framework unit tests
我正在使用 Spark 网络框架并创建 RESTful API。
(http://sparkjava.com 因为那里有多个名为 "Spark" 的东西)
我雇主的标准要求我们编写一系列单元测试,这些单元测试将每天自动 运行 一次以确认应用程序仍在运行。
Spark 很容易使用像 Postman 这样的工具来测试自己,但我还没有找到 JUnit
使用 Spark 甚至 HTTP 请求 编写测试的好例子以编程方式制作。
以前有人做过吗?可能吗?
我有同样的要求,你和我找到了一种方法让它发挥作用。
我搜索了 Spark 源代码,发现了两个有用的 classes:
- SparkTestUtil:此 class 包装 Apache HttpClient 并公开方法以对具有可自定义端口(在构造函数中)的本地 Web 服务器(本地主机中的运行)发出不同的 http 请求和相对路径(在请求方法中)
- ServletTest:它在具有应用程序上下文和相对目录路径的本地端口中启动 Jetty 实例,其中可以找到 WEB-INF/web.xml 文件描述符。此 web.xml 将用于模拟 Web 应用程序。然后它使用 SparkTestUtil 对该模拟应用程序发出 http 请求并断言结果。
这就是我所做的:我创建了一个实现 SparkApplication 接口的 junit 测试 class。在该界面中,我创建并初始化了 "controller"(我的应用程序的 class)负责回答 http 请求。在用 @BeforeClass 注释的方法中,我使用 web.xml 将 Junit 测试 class 称为 SparkApplication 和 SparkTestUtil[=14= 来初始化 Jetty 实例]
JUnit测试class
package com.test
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.webapp.WebAppContext;
public class ControllerTest implements SparkApplication {
private static SparkTestUtil sparkTestUtil;
private static Server webServer;
@Override
public void init() {
new Controller(...)
}
@BeforeClass
public static void beforeClass() throws Exception {
sparkTestUtil = new SparkTestUtil(PORT);
webServer = new Server();
ServerConnector connector = new ServerConnector(webServer);
connector.setPort(PORT);
webServer.setConnectors(new Connector[] {connector});
WebAppContext bb = new WebAppContext();
bb.setServer(webServer);
bb.setContextPath("/");
bb.setWar("src/test/webapp/");
webServer.setHandler(bb);
webServer.start();
(...)
}
@AfterClass
public static void afterClass() throws Exception {
webServer.stop();
(...)
}
}
src/test/webapp/WEB-INF/web.xml 文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>SparkFilter</filter-name>
<filter-class>spark.servlet.SparkFilter</filter-class>
<init-param>
<param-name>applicationClass</param-name>
<param-value>com.test.ControllerTest</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SparkFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
这可以改进,但我认为这是一个很好的起点。
也许可以创建一些 "spark-test" 组件?
希望这对你有用!
我们开发了一个小型库,可以方便地对 Spark 进行单元测试 controllers/endpoints。
此外,版本 1.1.3 已在 Maven 中央存储库中发布
<dependency>
<groupId>com.despegar</groupId>
<artifactId>spark-test</artifactId>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
这是我的 Solution.You 只需要额外添加 apache-http 和 junit 依赖项。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
public class SparkServer {
public static void main(String[] args) {
Spark.port(8888);
Spark.threadPool(1000, 1000,60000);
Spark.get("/ping", (req, res) -> "pong");
}
}
public class SparkTest {
@Before
public void setup() {
SparkServer.main(null);
}
@After
public void tearDown() throws Exception {
Thread.sleep(1000);
Spark.stop();
}
@Test
public void test() throws IOException {
CloseableHttpClient httpClient = HttpClients.custom()
.build();
HttpGet httpGet = new HttpGet("http://localhost:8888/ping");
CloseableHttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
assertEquals(200, statusCode);
assertEquals("pong", result.toString());
}
}
另一种方法是创建一个 class,它在每个 path
或 route
中实现路由。例如,如果您有如下一条路线:
get("maintenance/task", (req, response) -> {....});
然后用 class 实现 Route
.
替换 (req, response) -> {....}
lambda
例如:
public class YourRoute implements Route {
public Object handle(Request request, Response response) throws Exception {
....
}
}
将是:
get("maintenance/task", new YourRoute());
然后您可以使用 JUnit 进行单元测试 YourRoute
class。
我正在使用 Spark 网络框架并创建 RESTful API。 (http://sparkjava.com 因为那里有多个名为 "Spark" 的东西)
我雇主的标准要求我们编写一系列单元测试,这些单元测试将每天自动 运行 一次以确认应用程序仍在运行。
Spark 很容易使用像 Postman 这样的工具来测试自己,但我还没有找到 JUnit
使用 Spark 甚至 HTTP 请求 编写测试的好例子以编程方式制作。
以前有人做过吗?可能吗?
我有同样的要求,你和我找到了一种方法让它发挥作用。 我搜索了 Spark 源代码,发现了两个有用的 classes:
- SparkTestUtil:此 class 包装 Apache HttpClient 并公开方法以对具有可自定义端口(在构造函数中)的本地 Web 服务器(本地主机中的运行)发出不同的 http 请求和相对路径(在请求方法中)
- ServletTest:它在具有应用程序上下文和相对目录路径的本地端口中启动 Jetty 实例,其中可以找到 WEB-INF/web.xml 文件描述符。此 web.xml 将用于模拟 Web 应用程序。然后它使用 SparkTestUtil 对该模拟应用程序发出 http 请求并断言结果。
这就是我所做的:我创建了一个实现 SparkApplication 接口的 junit 测试 class。在该界面中,我创建并初始化了 "controller"(我的应用程序的 class)负责回答 http 请求。在用 @BeforeClass 注释的方法中,我使用 web.xml 将 Junit 测试 class 称为 SparkApplication 和 SparkTestUtil[=14= 来初始化 Jetty 实例]
JUnit测试class
package com.test
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.webapp.WebAppContext;
public class ControllerTest implements SparkApplication {
private static SparkTestUtil sparkTestUtil;
private static Server webServer;
@Override
public void init() {
new Controller(...)
}
@BeforeClass
public static void beforeClass() throws Exception {
sparkTestUtil = new SparkTestUtil(PORT);
webServer = new Server();
ServerConnector connector = new ServerConnector(webServer);
connector.setPort(PORT);
webServer.setConnectors(new Connector[] {connector});
WebAppContext bb = new WebAppContext();
bb.setServer(webServer);
bb.setContextPath("/");
bb.setWar("src/test/webapp/");
webServer.setHandler(bb);
webServer.start();
(...)
}
@AfterClass
public static void afterClass() throws Exception {
webServer.stop();
(...)
}
}
src/test/webapp/WEB-INF/web.xml 文件
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>SparkFilter</filter-name>
<filter-class>spark.servlet.SparkFilter</filter-class>
<init-param>
<param-name>applicationClass</param-name>
<param-value>com.test.ControllerTest</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SparkFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
这可以改进,但我认为这是一个很好的起点。 也许可以创建一些 "spark-test" 组件?
希望这对你有用!
我们开发了一个小型库,可以方便地对 Spark 进行单元测试 controllers/endpoints。
此外,版本 1.1.3 已在 Maven 中央存储库中发布
<dependency>
<groupId>com.despegar</groupId>
<artifactId>spark-test</artifactId>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
这是我的 Solution.You 只需要额外添加 apache-http 和 junit 依赖项。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
public class SparkServer {
public static void main(String[] args) {
Spark.port(8888);
Spark.threadPool(1000, 1000,60000);
Spark.get("/ping", (req, res) -> "pong");
}
}
public class SparkTest {
@Before
public void setup() {
SparkServer.main(null);
}
@After
public void tearDown() throws Exception {
Thread.sleep(1000);
Spark.stop();
}
@Test
public void test() throws IOException {
CloseableHttpClient httpClient = HttpClients.custom()
.build();
HttpGet httpGet = new HttpGet("http://localhost:8888/ping");
CloseableHttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
assertEquals(200, statusCode);
assertEquals("pong", result.toString());
}
}
另一种方法是创建一个 class,它在每个 path
或 route
中实现路由。例如,如果您有如下一条路线:
get("maintenance/task", (req, response) -> {....});
然后用 class 实现 Route
.
(req, response) -> {....}
lambda
例如:
public class YourRoute implements Route {
public Object handle(Request request, Response response) throws Exception {
....
}
}
将是:
get("maintenance/task", new YourRoute());
然后您可以使用 JUnit 进行单元测试 YourRoute
class。