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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:50:03  来源:igfitidea点击:

How to test a Jersey REST web service?

javarestunit-testingjunitjersey

提问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 ResourceConfigto the server with only the Serviceclass. 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 ResourceConfigconfiguration. In both examples above it is assumed the @Pathvalue for the Serviceclass is service, as you can see in the test URLs.

嵌入式 Grizzly 容器将根据您的ResourceConfig配置在幕后启动。在它上面的两个例子,假定@Path该值Serviceservice,你可以在测试网址中看到。

Some Resources

一些资源

Some Examples

一些例子



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

enter image description here

在此处输入图片说明

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 ResourceConfigin 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 ResourceConfigsubclass (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 ResourceConfigclass, you can just replace it in the configuremethod.

无论您使用的是 web.xml 还是ResourceConfig子类(如上所示),您都可以通过使用单独的ResourceConfig、内置于测试类中的 . 否则,如果您使用的是普通ResourceConfig类,则只需在configure方法中替换它即可。

The configuremethod, 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 @Testis 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 Clientby 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