[英]Spark web framework unit tests
I am working with the Spark web framework and creating a RESTful API . 我正在使用Spark Web框架并创建RESTful API 。 ( http://sparkjava.com since there are multiple things out there named "Spark")
( http://sparkjava.com因为有很多东西叫做“Spark”)
My employer's standards mandate that we write a series of unit tests that will be automatically run once a day to confirm that applications are still up. 我的雇主的标准要求我们编写一系列单元测试,每天自动运行一次,以确认应用程序仍在运行。
Spark is easy to test myself using a tool like Postman but I have not found any good examples of JUnit
tests being written with Spark or even with HTTP Requests being made programmatically with it. Spark很容易使用像Postman这样的工具来测试自己,但是我没有找到任何使用Spark编写的
JUnit
测试的好例子,甚至是用编程方式编写的HTTP请求 。
Has anyone done this before? 有没有人这样做过? Is it possible?
可能吗?
we have develop a small library that facilitates the unit testing of Spark controllers/endpoints. 我们开发了一个小型库,便于Spark控制器/端点的单元测试。
Also, the version 1.1.3 is published in Maven Central Repository 此外,版本1.1.3发布在Maven Central Repository中
<dependency>
<groupId>com.despegar</groupId>
<artifactId>spark-test</artifactId>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
I had the same requirement that you and I found a way to make it work. 我有同样的要求,你和我找到了让它运作的方法。 I searched over Spark source code and I found two classes that are useful:
我搜索了Spark源代码,发现了两个有用的类:
This is what I did: I created a junit test class that implements SparkApplication interface. 这就是我所做的:我创建了一个实现SparkApplication接口的junit测试类。 In that interface I create and initialize the "controller" (a class of my application) in charge of answer http requests.
在该接口中,我创建并初始化负责回答http请求的“控制器”(我的应用程序类)。 In a method annotated with @BeforeClass I initialize the Jetty instance using a web.xml that refers to the junit test class as the SparkApplication and a SparkTestUtil
在使用@BeforeClass注释的方法中,我使用web.xml初始化Jetty实例,该文件将junit测试类称为SparkApplication和SparkTestUtil
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();
(...)
}
}
<!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>
This can be improved, but it is a good starting point I think. 这可以改进,但我认为这是一个很好的起点。 Maybe some "spark-test" component could be created?
也许可以创建一些“火花测试”组件?
Hope this would be useful for you! 希望这对你有用!
Here is my Solution.You just need additional add apache-http and junit dependency. 这是我的解决方案。您只需要额外添加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());
}
}
Another approach wis to create a class which implements Route in each path
or route
. 另一种方法是创建一个在每个
path
或route
实现Route的类。 For example, if you have a route like next: 例如,如果您有下一条路线:
get("maintenance/task", (req, response) -> {....});
Then replace (req, response) -> {....}
lambda by a class implementing Route
. 然后用实现
Route
的类替换(req, response) -> {....}
lambda。
For example: 例如:
public class YourRoute implements Route {
public Object handle(Request request, Response response) throws Exception {
....
}
}
Would be: 将会:
get("maintenance/task", new YourRoute());
Then you can unit testing YourRoute
class using JUnit. 然后,您可以使用JUnit对
YourRoute
类进行单元测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.