如何对Tomcat上部署的Jersey Web应用程序进行单元测试? [英] How can I unit-test a Jersey web application deployed on Tomcat?

查看:167
本文介绍了如何对Tomcat上部署的Jersey Web应用程序进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm building a Jersey web application deployed on Tomcat. I'm having a hard time understanding how to unit test the app.

通过简单地在我的测试中实例化类并调用它们上的方法来测试核心业务逻辑(非Jersey资源类)是可能的(这无关紧要)使用Jersey或Tomcat)。

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资源类(即映射到URL的类)进行单元测试的正确方法是什么?

But what is the right way to unit test the Jersey resource classes (i.e., the classes that map to URLs)?

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

Do I need to have Tomcat running for this? Or should I mock the request and response objects, instantiate the resource classes in my tests, and feed the mocks to my classes?

我已阅读有关泽西岛网站测试的信息,但他们在他们的例子中使用Grizzly而不是Tomcat,这是不同的。

I have read about testing in Jersey's site, but they're using Grizzly and not Tomcat in their examples, which is different.

请解释如何做到这一点。欢迎使用示例代码。

Please explain how this should be done. Example code would be welcome.

推荐答案

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

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. A pretty popular mocking framework is 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"));
    }
}

另见:

  • How to get instance of javax.ws.rs.core.UriInfo

如果你想运行集成测试,我个人认为,无论你是否运行Grizzly容器而不是运行Tomcat容器,我都没有太大区别,只要你没有在你的应用程序中使用任何特定于Tomcat的东西。

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.

使用 Jersey测试框架是集成测试的一个很好的选择,但它们没有Tomcat提供程序。只有Grizzly,In-Memory和Jetty。如果您没有使用任何Servlet API,如 HttpServletRequest ServletContext 等,内存提供商可能是可行的解。它会给你更快的测试时间。

Using the Jersey Test Framework is a good option for integration testing, but they do not have a Tomcat provider. There is only Grizzly, In-Memory and Jetty. If you are not using any Servlet APIs like HttpServletRequest or ServletContext, etc, the In-Memory provider may be a viable solution. It will give you quicker test time.

参见:

  • junit 4 test case to test rest web service for some examples, aside from the ones given in the documentation.

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

If you must use Tomcat, you can run your own embedded Tomcat. I have not found much documentation, but there is an example in 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)

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

这篇关于如何对Tomcat上部署的Jersey Web应用程序进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆