如何使用Jersey Test Framework测试@WebServlet? (没有找到Http 404)

时间:2017-07-06 23:44:12

标签: java maven java-ee jersey jersey-test-framework

当我使用Jersey Test Framework为@Path的类运行我的Maven测试时,它运行正常。但是,当我尝试测试一个@WebServlet类时,它没有,并说它是404错误。

如何使用Jersey Test Framework测试Web servlet? (或者,如果这不可能,我还能怎么测试呢?)

Web Servlet:

package com.testservlet;


@WebServlet("/test")
public class TestServlet extends HttpServlet
{

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        resp.getWriter().println( "The Result" );
    }
}

测试类:

import com.testservlet.TestServlet;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Assert;
import org.junit.Test;

import javax.ws.rs.core.Application;

public class TestEndpoint extends JerseyTest
{
    @Override
    protected Application configure()
    {
        return new ResourceConfig( JPAServlet.class );
    }

    @Test
    public void baseGetTest()
    {
        String response = target( "/test" ).request().get( String.class );
        Assert.assertTrue( "92096".equals( response ) );
    }
}

的Maven:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>groupId</groupId>
    <artifactId>TestWeb</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <!-- Tell Maven what language version to use -->
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>


    <dependencies>

        <!-- Enables the annotations, etc needed -->
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.exterprise</groupId>
                    <artifactId>cdi-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Our jersey libs -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>2.25.1</version>
        </dependency>

        <!-- CDI to JAX-RS Binding -->
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.containers.glassfish/jersey-gf-cdi-ban-custom-hk2-binding -->
        <dependency>
            <groupId>org.glassfish.jersey.containers.glassfish</groupId>
            <artifactId>jersey-gf-cdi</artifactId>
            <version>2.14</version>
        </dependency>

        <!-- TESTING WEB -->
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-jdk-http</artifactId>
            <version>2.25.1</version>
        </dependency>

    </dependencies>

</project>

1 个答案:

答案 0 :(得分:1)

首先,您需要使用支持servlet部署的container,例如灰熊容器

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

然后,您需要将测试类配置为部署为servlet容器。

@Override
public TestContainerFactory getTestContainerFactory() {
    return new GrizzlyWebTestContainerFactory();
}

@Override
public DeploymentContext configureDeployment() {
    return ServletDeploymentContext.forServlet(TestServlet.class)
            .build();
}

在这里,您不需要像现在这样覆盖configure方法。但是,上述配置不配置Jersey应用程序。它只配置您的测试servlet。如果你想在servlet环境中运行Jersey(默认的JerseyTest不这样做),那么你可以配置Jersey这样的

@Override
public DeploymentContext configureDeployment() {
    final ResouceConfig config = ResourceConfig();
    return ServletDeploymentContext.builder(config)
            .build();
}

您可以使用ServletDeploymentContext配置许多其他内容;只看文档。

更新

而不是尝试启动服务器。您最好不要编写单元测试(而不是集成测试),而只需使用像Mockito这样的模拟框架来模拟依赖项。下面有一个例子。我添加了一些评论,每条线的作用。有关Mockito的更多信息,请参阅链接的文档。

public class WebServletTest {

    @Test
    public void testServletGet() throws Exception {
        // create some mocks
        SomeDao dao = mock(SomeDao.class);
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        PrintWriter writer = mock(PrintWriter.class);

        // do some stubbing
        when(response.getWriter()).thenReturn(writer);
        when(dao.getData(anyString())).thenReturn("Hello World");
        // used to capture argument to writer.println
        ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

        // create the servlet and call the method under test
        TestServlet servlet = new TestServlet(dao);
        servlet.doGet(request, response);

        // capture the argument to writer.println
        verify(writer).println(captor.capture());
        String arg = captor.getValue();

        // make assetions
        assertThat(arg).isEqualTo("Hello World");
    }

    private interface SomeDao {
        String getData(String param);
    }

    @WebServlet("/test")
    public static class TestServlet extends HttpServlet {
        private final SomeDao dao;

        @Inject
        public TestServlet(SomeDao dao) {
            this.dao = dao;
        }

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            resp.getWriter().println(this.dao.getData(""));
        }
    }
}