1

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

如何使用 Jersey 测试框架测试 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 ) );
    }
}

马文:

<?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>
4

1 回答 1

1

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

<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(""));
        }
    }
}
于 2017-07-07T01:57:27.337 回答