简体   繁体   English

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

[英]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.我已经在 J​​ersey 的站点上阅读了有关测试的信息,但是他们在示例中使用的是 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,如HttpServletRequestServletContext等,则 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.

相关问题 如何对 javanica @HystrixCommand 注释方法进行单元测试? - How can I unit-test javanica @HystrixCommand annotated methods? 如何对我的数据库内容进行单元测试? - How can I unit-test my database content? 如何在 @ComponentScan @Configuration 中使用数据源依赖项对 Spring 引导应用程序的 controller 进行单元测试 - How do I unit-test the controller of a Spring Boot application with a DataSource dependency in a @ComponentScan @Configuration 如何从部署在其上的Java Web应用程序访问tomcat日志文件? - How can I access tomcat log files from Java web application deployed on it? 我如何使用域直接访问部署在AWS tomcat中的Web应用程序而不显示端口? - how can i directly access my web application deployed in aws tomcat using domain without showing port? 我应该如何对长功能进行单元测试? - How should I unit-test a long function? Java,BigDecimal:如何对舍入错误进行单元测试? - Java, BigDecimal: How do I unit-test for rounding errors? 如何使用FileUtils对将文件保存到磁盘进行单元测试? - How do I unit-test saving file to the disk with FileUtils? 部署在Tomcat上的Jersey应用程序返回404 - Jersey application deployed on Tomcat returns 404 如何对双向文本处理进行单元测试 - How to unit-test bidirectional text handling
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM