如何在 Java 中模拟 Web 服务器以进行单元测试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/606352/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to mock a web server for unit testing in Java?
提问by jon077
I would like to create a unit test using a mock web server. Is there a web server written in Java which can be easily started and stopped from a JUnit test case?
我想使用模拟 Web 服务器创建单元测试。是否有可以从 JUnit 测试用例轻松启动和停止的用 Java 编写的 Web 服务器?
采纳答案by ng.
Try Simple(Maven) its very easy to embed in a unit test. Take the RoundTripTest and examples such as the PostTestwritten with Simple. Provides an example of how to embed the server into your test case.
试试Simple( Maven),它很容易嵌入到单元测试中。以 RoundTripTest 和使用 Simple 编写的PostTest等示例为例。提供如何将服务器嵌入到测试用例中的示例。
Also Simple is much lighter and faster than Jetty, with no dependencies. So you won't have to add several jar files onto your classpath. Nor will you have to be concerned with WEB-INF/web.xml
or any other artifacts.
此外,Simple 比 Jetty 更轻、更快,没有依赖关系。所以你不必在你的类路径中添加几个 jar 文件。您也不必担心WEB-INF/web.xml
或任何其他工件。
回答by flybywire
Try using the Jetty web server.
尝试使用Jetty Web 服务器。
回答by CoverosGene
Are you trying to use a mockor an embeddedweb server?
您是尝试使用模拟还是嵌入式Web 服务器?
For a mockweb server, try using Mockito, or something similar, and just mock the HttpServletRequest
and HttpServletResponse
objects like:
对于模拟Web 服务器,尝试使用Mockito或类似的东西,然后模拟HttpServletRequest
和HttpServletResponse
对象,例如:
MyServlet servlet = new MyServlet();
HttpServletRequest mockRequest = mock(HttpServletRequest.class);
HttpServletResponse mockResponse = mock(HttpServletResponse.class);
StringWriter out = new StringWriter();
PrintWriter printOut = new PrintWriter(out);
when(mockResponse.getWriter()).thenReturn(printOut);
servlet.doGet(mockRequest, mockResponse);
verify(mockResponse).setStatus(200);
assertEquals("my content", out.toString());
For an embeddedweb server, you could use Jetty, which you can use in tests.
回答by Haroldo_OK
Another good alternative would be MockServer; it provides a fluent interface with which you can define the behaviour of the mocked web server.
另一个不错的选择是MockServer;它提供了一个流畅的界面,您可以使用它来定义模拟的 Web 服务器的行为。
回答by keaplogik
Wire Mockseems to offer a solid set of stubs and mocks for testing external web services.
Wire Mock似乎提供了一组可靠的存根和模拟来测试外部 Web 服务。
@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);
@Test
public void exactUrlOnly() {
stubFor(get(urlEqualTo("/some/thing"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("Hello world!")));
assertThat(testClient.get("/some/thing").statusCode(), is(200));
assertThat(testClient.get("/some/thing/else").statusCode(), is(404));
}
It can integrate with spock as well. Example found here.
它也可以与 spock 集成。示例在这里找到。
回答by Jan Dudek
You can try Jadlerwhich is a library with a fluent programmatic Java API to stub and mock http resources in your tests. Example:
您可以尝试使用Jadler,它是一个具有流畅编程 Java API 的库,可以在您的测试中存根和模拟 http 资源。例子:
onRequest()
.havingMethodEqualTo("GET")
.havingPathEqualTo("/accounts/1")
.havingBody(isEmptyOrNullString())
.havingHeaderEqualTo("Accept", "application/json")
.respond()
.withDelay(2, SECONDS)
.withStatus(200)
.withBody("{\"account\":{\"id\" : 1}}")
.withEncoding(Charset.forName("UTF-8"))
.withContentType("application/json; charset=UTF-8");
回答by jkschneider
You can write a mock with the JDK's com.sun.net.httpserver.HttpServer
class as well (no external dependencies required). See this blog postdetailing how.
您也可以使用 JDK 的com.sun.net.httpserver.HttpServer
类编写模拟(不需要外部依赖项)。请参阅此博客文章,详细说明如何操作。
In summary:
总之:
HttpServer httpServer = HttpServer.create(new InetSocketAddress(8000), 0); // or use InetSocketAddress(0) for ephemeral port
httpServer.createContext("/api/endpoint", new HttpHandler() {
public void handle(HttpExchange exchange) throws IOException {
byte[] response = "{\"success\": true}".getBytes();
exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
exchange.getResponseBody().write(response);
exchange.close();
}
});
httpServer.start();
try {
// Do your work...
} finally {
httpServer.stop(0); // or put this in an @After method or the like
}
回答by s-han.lee
If you are using apache HttpClient, This will be a good alternative. HttpClientMock
如果您使用的是 apache HttpClient,这将是一个不错的选择。 HttpClientMock
HttpClientMock httpClientMock = new httpClientMock()
HttpClientMock("http://example.com:8080");
httpClientMock.onGet("/login?user=john").doReturnJSON("{permission:1}");
Basically, you then make requests on your mock object and then can do some verifies on it httpClientMock.verify().get("http://localhost/login").withParameter("user","john").called()
基本上,您然后对您的模拟对象发出请求,然后可以对其进行一些验证 httpClientMock.verify().get("http://localhost/login").withParameter("user","john").called()
回答by rogerdpack
In the interest of completeness there is also wrapping jetty with camelto make it slightly more user friendly.
为了完整起见,还用骆驼包裹码头,使其更加用户友好。
make your test class extend CamelTestSupport
then define a route ex:
让你的测试类扩展CamelTestSupport
然后定义一个路由:
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
from("jetty:http://localhost:" + portToUse).process(
new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
// Get the request information.
requestReceivedByServer = (String) exchange.getIn().getHeader(Exchange.HTTP_PATH);
// For testing empty response
exchange.getOut().setBody("your response");
....
example maven dependencies to get it:
获取它的示例 maven 依赖项:
<dependency> <!-- used at runtime, by camel in the tests -->
<groupId>org.apache.camel</groupId>
<artifactId>camel-jetty</artifactId>
<version>2.12.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.12.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test</artifactId>
<version>2.12.1</version>
<scope>test</scope>
</dependency>
回答by Frank Neblung
I recommend Javalin. It's an excellent tool for mocking the real service as it allows for state assertions in your tests (server side assertions).
我推荐Javalin。它是模拟真实服务的绝佳工具,因为它允许在测试中进行状态断言(服务器端断言)。
Wiremockcan be used as well. But it leads to hard to maintain behavioral tests (verify that client calls are as expected).
也可以使用Wiremock。但这会导致难以维护行为测试(验证客户端调用是否符合预期)。