Java 如何测试 Jersey REST Web 服务?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29358940/
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 test a Jersey REST web service?
提问by Jenny
I have written a Restful Web service and have to test it using JUnit4. I have already written a Client using Jersey Client. But want to know if I can test my service only with junit4. Can someone help me with sample at least.
我编写了一个 Restful Web 服务并且必须使用 JUnit4 对其进行测试。我已经使用 Jersey 客户端编写了一个客户端。但想知道我是否只能使用 junit4 测试我的服务。至少有人可以帮我提供样品。
My rest service has authenticate method that takes user name, password and returns a token.
我的休息服务具有使用用户名、密码并返回令牌的身份验证方法。
I have written test case for authenticate method. But I am not sure how to test using url.
我已经为身份验证方法编写了测试用例。但我不确定如何使用 url 进行测试。
public class TestAuthenticate {
Service service = new Service();
String username = "user";
String password = "password";
String token;
@Test(expected = Exception.class)
public final void testAuthenticateInputs() {
password = "pass";
service.authenticate(username, password);
}
@Test(expected = Exception.class)
public final void testAuthenticateException(){
username = null;
String token = service.authenticate(username, password);
assertNotNull(token);
}
@Test
public final void testAuthenticateResult() {
String token = service.authenticate(username, password);
assertNotNull(token);
}
}
采纳答案by Paul Samsotha
If you want to test using the URL, then you will need to start a server from your test. You can explicitly start an embedded server, which is pretty common for tests. Something like
如果要使用 URL 进行测试,则需要从测试中启动服务器。您可以显式启动嵌入式服务器,这在测试中很常见。就像是
public class MyResourceTest {
public static final String BASE_URI = "http://localhost:8080/api/";
private HttpServer server;
@Before
public void setUp() throws Exception {
final ResourceConfig rc = new ResourceConfig(Service.class);
server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
}
@After
public void tearDown() throws Exception {
server.stop();
}
@Test
public void testService() {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(BASE_URI).path("service");
...
}
}
It's basically an integration test. You're starting the Grizzly container and loading a ResourceConfig
to the server with only the Service
class. Of course you could add more classes to the configuration. You can use "real" resource config if you wanted.
它基本上是一个集成测试。您正在启动 Grizzly 容器并ResourceConfig
仅使用Service
该类将 a 加载到服务器。当然,您可以在配置中添加更多类。如果需要,您可以使用“真实”资源配置。
The above test uses this dependency
上面的测试使用了这个依赖
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<version>${jersey2.version}</version>
</dependency>
Another option, which is the one I prefer, is to make use of the Jersey Test Framework, which will start an embedded container for you. A test might look something more like
我更喜欢的另一种选择是使用Jersey 测试框架,它将为您启动一个嵌入式容器。测试可能看起来更像
public class SimpleTest extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(Service.class);
}
@Test
public void test() {
String hello = target("service").request().get(String.class);
}
}
Using this dependency
使用这个依赖
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey2.version}</version>
<scope>test</scope>
</dependency>
And embedded Grizzly container will get started under the hood, with your ResourceConfig
configuration. In both examples above it is assumed the @Path
value for the Service
class is service
, as you can see in the test URLs.
嵌入式 Grizzly 容器将根据您的ResourceConfig
配置在幕后启动。在它上面的两个例子,假定@Path
该值Service
类service
,你可以在测试网址中看到。
Some Resources
一些资源
Some Examples
一些例子
- How to write Unit Test for this class using Jersey 2 test framework
- How to in-memory unit test Spring-Jersey
- Example with Mockito, Test Framework, and Jersey 2
- Example with Mockito, Test Framework, and Jersey 1
- 如何使用 Jersey 2 测试框架为此类编写单元测试
- 如何在内存中单元测试 Spring-Jersey
- Mockito、测试框架和 Jersey 2 的示例
- Mockito、测试框架和 Jersey 1 的示例
UPDATE
更新
If you're not using Maven, here are the jars you will need to run an embedded Grizzly container for the Jersey Test Fraemwork
如果您不使用 Maven,这里是运行 Jersey 测试框架的嵌入式 Grizzly 容器所需的 jars
I usually search for all my jars here. You can select the version and there should be a link in the next page, to download. You can use the search bar to search for the others.
我通常在这里搜索我所有的罐子。您可以选择版本,下一页应该有一个链接,可以下载。您可以使用搜索栏搜索其他人。
Here's a simple running example, once you have all the jars
这是一个简单的运行示例,一旦你拥有了所有的罐子
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.spi.container.servlet.WebComponent;
import com.sun.jersey.test.framework.JerseyTest;
import com.sun.jersey.test.framework.WebAppDescriptor;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import junit.framework.Assert;
import org.junit.Test;
public class SimpleTest extends JerseyTest {
@Path("service")
public static class Service {
@GET
public String getTest() { return "Hello World!"; }
}
public static class AppConfig extends DefaultResourceConfig {
public AppConfig() {
super(Service.class);
}
}
@Override
public WebAppDescriptor configure() {
return new WebAppDescriptor.Builder()
.initParam(WebComponent.RESOURCE_CONFIG_CLASS,
AppConfig.class.getName())
.build();
}
@Test
public void doTest() {
WebResource resource = resource().path("service");
String result = resource.get(String.class);
Assert.assertEquals("Hello World!", result);
System.out.println(result);
}
}
You're most likely not going to have the resources and ResourceConfig
in the same class as the test, but I just want to keep it simple and all visible in one class.
您很可能没有资源并且不会ResourceConfig
与测试在同一个班级,但我只想保持简单,并且在一个班级中全部可见。
Whether you are using a web.xml or a ResourceConfig
subclass (as shown above), you can cut down what you test by using a separate ResourceConfig
, built in the test class, as I have done. Otherwise, if you are using your normal ResourceConfig
class, you can just replace it in the configure
method.
无论您使用的是 web.xml 还是ResourceConfig
子类(如上所示),您都可以通过使用单独的ResourceConfig
、内置于测试类中的 . 否则,如果您使用的是普通ResourceConfig
类,则只需在configure
方法中替换它即可。
The configure
method, is pretty much just building a web.xml file, just in Java code. You can see different methods in the WebAppDescriptor.Builder
, like initParam
, which is the same as an <init-param>
in your web xml. You can simply use the string in the arguments, but there are some constants, as I used above.
该configure
方法几乎只是用 Java 代码构建一个 web.xml 文件。您可以在WebAppDescriptor.Builder
, like 中看到不同的方法initParam
,这与<init-param>
您的 web xml 中的an 相同。您可以简单地在参数中使用字符串,但有一些常量,正如我上面使用的那样。
The @Test
is you usual JUnit test that will run. It is using the Jersey Client. But instead of creating the Client
, you can simply just use the preconfigured Client
by just accessing the resource()
method, which returns a WebResource
. If you are familiar with the Jersey Client, then this class should not be new to you.
该@Test
是你常用的JUnit测试将运行。它正在使用 Jersey 客户端。但是Client
,您无需创建,Client
只需访问resource()
方法即可简单地使用预先配置的,该方法返回WebResource
. 如果您熟悉 Jersey Client,那么这个类对您来说应该不陌生。
回答by Ashish Shinde
Take a look at Alchemy rest client generator. This can generate a proxy implementation for your JAX-RS webservice class using jersey client behind the scene. Effectively you will call you webservice methods as simple java methods from your unit tests. Handles http authentication as well.
看看Alchemy 休息客户端生成器。这可以在幕后使用 jersey 客户端为您的 JAX-RS web 服务类生成代理实现。实际上,您将从单元测试中将 Web 服务方法称为简单的 java 方法。也处理 http 身份验证。
There is no code generation involved if you need to simply run tests so it is convenient.
如果您需要简单地运行测试,则不涉及代码生成,因此很方便。
The demo heresetup up grizzly and uses the generator above to run junit tests.
这里的演示设置了 grizzly 并使用上面的生成器来运行 junit 测试。
Disclaimer: I am the author of this library.
免责声明:我是这个库的作者。
回答by keyoxy
I think @peeskillet has given you the needed prerequisites, i.e you need to run your web-service in an embedded web server. You could also look into dropwizard or spring-boot support for doing this conveniently.
我认为@peeskillet 为您提供了所需的先决条件,即您需要在嵌入式 Web 服务器中运行您的 Web 服务。您还可以查看 dropwizard 或 spring-boot 支持以方便地执行此操作。
As for actually verifying the response I would keep it simple and go with JUnit & http-matchers (see https://github.com/valid4j/http-matchers)
至于实际验证响应,我会保持简单并使用 JUnit 和 http-matchers(参见https://github.com/valid4j/http-matchers)