gpt4 book ai didi

java - 如何对部署在 Tomcat 上的 Jersey Web 应用程序进行单元测试?

转载 作者:行者123 更新时间:2023-11-30 08:37:28 36 4
gpt4 key购买 nike

我正在构建部署在 Tomcat 上的 Jersey Web 应用程序。我很难理解如何对应用程序进行单元测试。

只需在我的测试中实例化类并调用它们的方法(这与 Jersey 或 Tomcat 无关),就可以测试核心业务逻辑(非 Jersey 资源类)。

但是对 Jersey 资源类(即映射到 URL 的类)进行单元测试的正确方法是什么?

我需要为此运行 Tomcat 吗?或者我应该模拟请求和响应对象,在我的测试中实例化资源类,并将模拟提供给我的类吗?

我在 Jersey 的网站上读到过有关测试的信息,但他们在示例中使用的是 Grizzly 而不是 Tomcat,这是不同的。

请解释应该如何完成。欢迎使用示例代码。

最佳答案

如果您只想单元 测试,则无需启动任何服务器。如果您有服务(业务层)或任何其他注入(inject),如 UriInfo 和类似性质的东西,您可以模拟。一个非常流行的模拟框架是 Mockito .下面是一个完整的例子

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

/**
* Beside Jersey dependencies, you will need Mockito.
*
* <dependency>
* <groupId>org.mockito</groupId>
* <artifactId>mockito-core</artifactId>
* <version>1.10.19</version>
* </dependency>
*
* @author Paul Samsotha
*/
public class SomethingResourceUnitTest {

public static interface SomeService {
String getSomethingById(int id);
}

@Path("something")
public static class SomethingResource {

private final SomeService service;

@Inject
public SomethingResource(SomeService service) {
this.service = service;
}

@GET
@Path("{id}")
public Response getSomethingById(@PathParam("id") int id) {
String result = service.getSomethingById(id);
return Response.ok(result).build();
}
}

private SomethingResource resource;
private SomeService service;

@Before
public void setUp() {
service = Mockito.mock(SomeService.class);
resource = new SomethingResource(service);
}

@Test
public void testGetSomethingById() {
Mockito.when(service.getSomethingById(Mockito.anyInt())).thenReturn("Something");

Response response = resource.getSomethingById(1);
assertThat(response.getStatus(), is(200));
assertThat(response.getEntity(), instanceOf(String.class));
assertThat((String)response.getEntity(), is("Something"));
}
}

另请参阅:


如果你想运行一个集成测试,我个人认为无论你运行的是 Grizzly 容器还是运行 Tomcat 容器,只要你不使用在您的应用程序中任何特定于 Tomcat 的内容。

使用 Jersey Test Framework是集成测试的不错选择,但他们没有 Tomcat 提供程序。只有 Grizzly、In-Memory 和 Jetty。如果您不使用任何 Servlet API,例如 HttpServletRequestServletContext 等,In-Memory 提供程序可能是一个可行的解决方案。它会给你更快的测试时间。

另请参阅:


如果您必须使用 Tomcat,您可以运行您自己的嵌入式 Tomcat。我没有找到太多文档,但有一个 example in DZone .我并没有真正使用嵌入式 Tomcat,但是按照上一个链接中的示例,您可以得到类似以下内容(已经过测试可以工作)

import java.io.File;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

/**
* Aside from the Jersey dependencies, you will need the following
* Tomcat dependencies.
*
* <dependency>
* <groupId>org.apache.tomcat.embed</groupId>
* <artifactId>tomcat-embed-core</artifactId>
* <version>8.5.0</version>
* <scope>test</scope>
* </dependency>
* <dependency>
* <groupId>org.apache.tomcat.embed</groupId>
* <artifactId>tomcat-embed-logging-juli</artifactId>
* <version>8.5.0</version>
* <scope>test</scope>
* </dependency>
*
* See also https://dzone.com/articles/embedded-tomcat-minimal
*
* @author Paul Samsotha
*/
public class SomethingResourceTomcatIntegrationTest {

public static interface SomeService {
String getSomethingById(int id);
}

public static class SomeServiceImpl implements SomeService {
@Override
public String getSomethingById(int id) {
return "Something";
}
}

@Path("something")
public static class SomethingResource {

private final SomeService service;

@Inject
public SomethingResource(SomeService service) {
this.service = service;
}

@GET
@Path("{id}")
public Response getSomethingById(@PathParam("id") int id) {
String result = service.getSomethingById(id);
return Response.ok(result).build();
}
}

private Tomcat tomcat;

@Before
public void setUp() throws Exception {
tomcat = new Tomcat();
tomcat.setPort(8080);

final Context ctx = tomcat.addContext("/", new File(".").getAbsolutePath());

final ResourceConfig config = new ResourceConfig(SomethingResource.class)
.register(new AbstractBinder() {
@Override
protected void configure() {
bind(SomeServiceImpl.class).to(SomeService.class);
}
});
Tomcat.addServlet(ctx, "jersey-test", new ServletContainer(config));
ctx.addServletMapping("/*", "jersey-test");

tomcat.start();
}

@After
public void tearDown() throws Exception {
tomcat.stop();
}

@Test
public void testGetSomethingById() {
final String baseUri = "http://localhost:8080";
final Response response = ClientBuilder.newClient()
.target(baseUri).path("something").path("1")
.request().get();
assertThat(response.getStatus(), is(200));
assertThat(response.readEntity(String.class), is("Something"));
}
}

关于java - 如何对部署在 Tomcat 上的 Jersey Web 应用程序进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37221498/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com