如何测试 Jersey REST Web 服务?

How to test a Jersey REST web service?

我已经编写了一个 Restful Web 服务并且必须使用 JUnit4 对其进行测试。我已经使用 Jersey Client 编写了一个客户端。但是想知道我是否只能用 junit4 测试我的服务。有人可以至少帮我做样品吗?

我的休息服务有验证方法,采用用户名、密码和 returns 令牌。

我已经为身份验证方法编写了测试用例。但我不确定如何使用 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);
    }
}

如果您想使用 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");
        ...
    }
}

这基本上是一个集成测试。您正在启动 Grizzly 容器并将 ResourceConfig 加载到仅包含 Service class 的服务器。当然,您可以在配置中添加更多 classes。如果需要,您可以使用“真实”资源配置。

上面的测试使用了这个依赖

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-grizzly2-http</artifactId>
    <version>${jersey2.version}</version>
</dependency>

我更喜欢的另一种选择是使用 Jersey Test Framework,它将为您启动一个嵌入式容器。测试可能看起来更像

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);
    }
}

使用此依赖项

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>${jersey2.version}</version>
    <scope>test</scope>
</dependency>

嵌入式 Grizzly 容器将在后台启动,使用您的 ResourceConfig 配置。在上面的两个示例中,假设 Service class 的 @Path 值为 service,正如您在测试 URLs.[=43 中看到的那样=]

一些资源

一些例子

  • Example with Mockito, Test Framework, and Jersey 2
  • Example with Mockito, Test Framework, and Jersey 1

更新

如果您不使用 Maven,这里是您需要的罐子 运行 用于 Jersey Test Fraemwork 的嵌入式 Grizzly 容器

我通常会搜索我所有的罐子 here。你可以select版本,下一页应该有link,下载。您可以使用搜索栏搜索其他人。

这是一个简单的 运行ning 示例,一旦您拥有所有 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);
    }
}

您很可能不会在与测试相同的 class 中获得资源和 ResourceConfig,但我只想保持简单,并且在一个 [=97] 中全部可见=].

无论您使用的是 web.xml 还是 ResourceConfig subclass(如上所示),您都可以使用单独的 ResourceConfig 来减少测试内容,内置于测试 class,正如我所做的那样。否则,如果您使用的是正常的 ResourceConfig class,您可以在 configure 方法中替换它。

configure 方法几乎只是在 Java 代码中构建一个 web.xml 文件。您可以在 WebAppDescriptor.Builder 中看到不同的方法,例如 initParam,这与您的网络 xml 中的 <init-param> 相同。您可以简单地在参数中使用字符串,但是有一些常量,正如我在上面使用的那样。

@Test 是您常用的 JUnit 测试,它将 运行。它正在使用 Jersey 客户端。但是,您无需创建 Client,只需访问 resource() 方法即可使用预配置的 Client,其中 returns 和 WebResource。如果您熟悉 Jersey Client,那么这个 class 对您来说应该不陌生。

看看Alchemy rest client generator。这可以在后台使用 jersey 客户端为您的 JAX-RS web 服务 class 生成代理实现。实际上,您会将网络服务方法称为单元测试中的简单 java 方法。也处理 http 身份验证。

如果您只需要 运行 测试,则不涉及代码生成,因此很方便。

demo here 设置 grizzly 并使用上面的生成器进行 运行 junit 测试。

免责声明:我是这个库的作者。

我认为@peeskillet 已经为您提供了所需的先决条件,即您需要 运行 在嵌入式 Web 服务器中使用您的 Web 服务。您还可以查看 dropwizard 或 spring-boot 支持以方便地执行此操作。

至于实际验证响应,我会保持简单并使用 JUnit 和 http-matchers(参见 https://github.com/valid4j/http-matchers