[英]How can I unit-test a Jersey web application deployed on Tomcat?
I'm building a Jersey web application deployed on Tomcat.我正在构建部署在 Tomcat 上的 Jersey Web 应用程序。 I'm having a hard time understanding how to unit test the app.
我很难理解如何对应用程序进行单元测试。
Testing the core business logic (the non-Jersey-resource classes) is possible by simply instantiating the classes in my tests and calling methods on them (this has nothing to do with Jersey or Tomcat).通过简单地实例化我的测试中的类并调用它们的方法(这与 Jersey 或 Tomcat 无关),可以测试核心业务逻辑(非 Jersey 资源类)。
But what is the right way to unit test the Jersey resource classes (ie, the classes that map to URLs)?但是,单元测试 Jersey 资源类(即映射到 URL 的类)的正确方法是什么?
Do I need to have Tomcat running for this?我需要为此运行Tomcat吗? Or should I mock the request and response objects, instantiate the resource classes in my tests, and feed the mocks to my classes?
或者我应该模拟请求和响应对象,在我的测试中实例化资源类,并将模拟提供给我的类?
I have read about testing in Jersey's site, but they're using Grizzly and not Tomcat in their examples, which is different.我已经在 Jersey 的站点上阅读了有关测试的信息,但是他们在示例中使用的是 Grizzly 而不是 Tomcat,这是不同的。
Please explain how this should be done.请解释如何做到这一点。 Example code would be welcome.
欢迎使用示例代码。
If you just want to unit test, there's no need to start any server.如果您只想进行单元测试,则无需启动任何服务器。 If you have an services (business layer) or any other injections like
UriInfo
and things of that nature, you can just mock the.如果您有一个服务(业务层)或任何其他注入,如
UriInfo
和类似性质的东西,您可以模拟它。 A pretty popular mocking framework is Mockito .一个非常流行的模拟框架是Mockito 。 Below is a complete example
下面是一个完整的例子
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"));
}
}
See Also:也可以看看:
If you want to run an integration test, personally I don't see much difference whether or not you are running a Grizzly container vs. running a Tomcat container, as long as you are not using anything specific to Tomcat in your application.如果您想运行集成测试,我个人认为运行 Grizzly 容器与运行 Tomcat 容器并没有太大区别,只要您没有在应用程序中使用任何特定于 Tomcat 的东西。
Using the Jersey Test Framework is a good option for integration testing, but they do not have a Tomcat provider.使用Jersey 测试框架是集成测试的一个不错的选择,但它们没有 Tomcat 提供程序。 There is only Grizzly, In-Memory and Jetty.
只有 Grizzly、In-Memory 和 Jetty。 If you are not using any Servlet APIs like
HttpServletRequest
or ServletContext
, etc, the In-Memory provider may be a viable solution.如果您没有使用任何 Servlet API,如
HttpServletRequest
或ServletContext
等,则 In-Memory 提供程序可能是一个可行的解决方案。 It will give you quicker test time.它将为您提供更快的测试时间。
See Also:也可以看看:
If you must use Tomcat, you can run your own embedded Tomcat.如果必须使用 Tomcat,则可以运行自己的嵌入式 Tomcat。 I have not found much documentation, but there is an example in DZone .
我没有找到太多文档,但在 DZone 中有一个例子。 I don't really use the embedded Tomcat, but going of the example in the previous link, you can have something like the following (which has been tested to work)
我并没有真正使用嵌入式 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"));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.