单元测试 Java Spark 微框架
Unit testing Java Spark microframework
我正在尝试将 restful api 添加到 java 微服务。为此,我正在使用 spark:
http://sparkjava.com/documentation.html
我创建了一个非常简单的 class,它代表了一个 api。 class 在这里:
public class Routes {
public void establishRoutes(){
get("/test", (req, res) -> "Hello World");
after((req, res) -> {
res.type("application/json");
});
exception(IllegalArgumentException.class, (e, req, res) -> {
res.status(400);
});
}
现在,运行 Routes.establishRoutes() 应该建立一个 api,如果有人决定访问 http://localhost:4567/test,它会显示 "Hello World"。这确实有效。万岁!
下一步是对代码进行单元测试。不幸的是,我的单元测试没有成功。 spark 文档没有详细说明进行测试的合理方法,所以我所拥有的是从我在网上找到的示例拼凑而成的。这是我的 Junit 测试:
public class TestRoutes {
@Before
public void setUp() throws Exception {
Routes newRoutes = new Routes();
newRoutes.establishRoutes();
}
@After
public void tearDown() throws Exception {
stop();
}
@Test
public void testModelObjectsPOST(){
String testUrl = "/test";
ApiTestUtils.TestResponse res = ApiTestUtils.request("GET", testUrl, null);
Map<String, String> json = res.json();
assertEquals(201, res.status);
}
下面是 ApiTestUtils.request() 背后的代码:
public class ApiTestUtils {
public static TestResponse request(String method, String path, String requestBody) {
try {
URL url = new URL("http://localhost:4567" + path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(method);
connection.setDoOutput(true);
connection.connect();
String body = IOUtils.toString(connection.getInputStream());
return new TestResponse(connection.getResponseCode(), body);
} catch (IOException e) {
e.printStackTrace();
fail("Sending request failed: " + e.getMessage());
return null;
}
}
public static class TestResponse {
public final String body;
public final int status;
public TestResponse(int status, String body) {
this.status = status;
this.body = body;
}
public Map<String,String> json() {
return new Gson().fromJson(body, HashMap.class);
}
}
}
我在 ApiTestUtils.request()
内的 connection.connect()
上失败了。具体来说,我收到错误:java.lang.AssertionError: Sending request failed: Connection refused
我相信这是因为当我的测试试图发出请求时应用程序没有监听。但是,我不明白为什么会这样。我从这里的演示项目中借用了测试代码:
https://github.com/mscharhag/blog-examples/blob/master/sparkdemo/src/test/java/com/mscharhag/sparkdemo/UserControllerIntegrationTest.java
更新:
我试过 运行 上面链接的例子。事实证明,它也不起作用。看起来在这种情况下启动一个 spark 实例比我想象的更难?我不是想弄清楚该怎么做。
我无法在 Spark 方面为您提供帮助,但如果您愿意尝试使用其他轻量级 Java 库来编写微服务,请查看 Molecule。
您将找到编写单元测试和集成测试的文档和示例。如果我理解您要正确测试的内容,测试将如下所示:
HttpRequest request = new HttpRequest(4567);
HttpResponse response = request.get("/test");
assertThat(response).hasStatusCode(201)
.hasContentType("application/json")
.hasBodyText("Hello World");
在您的测试用例中缺少用于等待嵌入式服务器初始化的代码。
我已经尝试了您的代码并偶然发现了与您相同的问题,但在调试之后我注意到嵌入式 spark 服务器是在新创建的线程中初始化的。 (参见方法spark.Service#init()
)。
您在测试中需要做的就是通过调用方法 spark.Spark#awaitInitialization()
等待初始化
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static junit.framework.TestCase.assertEquals;
import static spark.Spark.awaitInitialization;
import static spark.Spark.stop;
public class TestRoutes {
@Before
public void setUp() throws Exception {
Routes newRoutes = new Routes();
newRoutes.establishRoutes();
awaitInitialization();
}
@After
public void tearDown() throws Exception {
stop();
}
@Test
public void testModelObjectsPOST() {
String testUrl = "/test";
ApiTestUtils.TestResponse res = ApiTestUtils.request("GET", testUrl, null);
assertEquals(200, res.status);
}
}
我正在尝试将 restful api 添加到 java 微服务。为此,我正在使用 spark:
http://sparkjava.com/documentation.html
我创建了一个非常简单的 class,它代表了一个 api。 class 在这里:
public class Routes {
public void establishRoutes(){
get("/test", (req, res) -> "Hello World");
after((req, res) -> {
res.type("application/json");
});
exception(IllegalArgumentException.class, (e, req, res) -> {
res.status(400);
});
}
现在,运行 Routes.establishRoutes() 应该建立一个 api,如果有人决定访问 http://localhost:4567/test,它会显示 "Hello World"。这确实有效。万岁!
下一步是对代码进行单元测试。不幸的是,我的单元测试没有成功。 spark 文档没有详细说明进行测试的合理方法,所以我所拥有的是从我在网上找到的示例拼凑而成的。这是我的 Junit 测试:
public class TestRoutes {
@Before
public void setUp() throws Exception {
Routes newRoutes = new Routes();
newRoutes.establishRoutes();
}
@After
public void tearDown() throws Exception {
stop();
}
@Test
public void testModelObjectsPOST(){
String testUrl = "/test";
ApiTestUtils.TestResponse res = ApiTestUtils.request("GET", testUrl, null);
Map<String, String> json = res.json();
assertEquals(201, res.status);
}
下面是 ApiTestUtils.request() 背后的代码:
public class ApiTestUtils {
public static TestResponse request(String method, String path, String requestBody) {
try {
URL url = new URL("http://localhost:4567" + path);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod(method);
connection.setDoOutput(true);
connection.connect();
String body = IOUtils.toString(connection.getInputStream());
return new TestResponse(connection.getResponseCode(), body);
} catch (IOException e) {
e.printStackTrace();
fail("Sending request failed: " + e.getMessage());
return null;
}
}
public static class TestResponse {
public final String body;
public final int status;
public TestResponse(int status, String body) {
this.status = status;
this.body = body;
}
public Map<String,String> json() {
return new Gson().fromJson(body, HashMap.class);
}
}
}
我在 ApiTestUtils.request()
内的 connection.connect()
上失败了。具体来说,我收到错误:java.lang.AssertionError: Sending request failed: Connection refused
我相信这是因为当我的测试试图发出请求时应用程序没有监听。但是,我不明白为什么会这样。我从这里的演示项目中借用了测试代码: https://github.com/mscharhag/blog-examples/blob/master/sparkdemo/src/test/java/com/mscharhag/sparkdemo/UserControllerIntegrationTest.java
更新: 我试过 运行 上面链接的例子。事实证明,它也不起作用。看起来在这种情况下启动一个 spark 实例比我想象的更难?我不是想弄清楚该怎么做。
我无法在 Spark 方面为您提供帮助,但如果您愿意尝试使用其他轻量级 Java 库来编写微服务,请查看 Molecule。
您将找到编写单元测试和集成测试的文档和示例。如果我理解您要正确测试的内容,测试将如下所示:
HttpRequest request = new HttpRequest(4567);
HttpResponse response = request.get("/test");
assertThat(response).hasStatusCode(201)
.hasContentType("application/json")
.hasBodyText("Hello World");
在您的测试用例中缺少用于等待嵌入式服务器初始化的代码。
我已经尝试了您的代码并偶然发现了与您相同的问题,但在调试之后我注意到嵌入式 spark 服务器是在新创建的线程中初始化的。 (参见方法spark.Service#init()
)。
您在测试中需要做的就是通过调用方法 spark.Spark#awaitInitialization()
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static junit.framework.TestCase.assertEquals;
import static spark.Spark.awaitInitialization;
import static spark.Spark.stop;
public class TestRoutes {
@Before
public void setUp() throws Exception {
Routes newRoutes = new Routes();
newRoutes.establishRoutes();
awaitInitialization();
}
@After
public void tearDown() throws Exception {
stop();
}
@Test
public void testModelObjectsPOST() {
String testUrl = "/test";
ApiTestUtils.TestResponse res = ApiTestUtils.request("GET", testUrl, null);
assertEquals(200, res.status);
}
}