【问题标题】:Jersey 2 Spring Integration testing setupJersey 2 Spring 集成测试设置
【发布时间】:2015-11-10 11:08:41
【问题描述】:

我正在开发一个使用 Jersey 2(用于 REST API)和 Spring(用于 DI)实现的 REST 项目,我想编写功能/集成测试。 我尝试使用 JerseyTest 框架并为这些测试使用真实的数据库。我唯一想模拟的是我的应用程序使用的远程 Web 服务 (SOAP),我应该为此模拟生成的 WS 客户端。

在花费大量时间研究 JerseyTest 框架与 Jersey2 和 Spring 之后,似乎不可能为集成测试设置该设置。你能告诉我你是否成功设置了类似的东西?

JerseyTest 的问题是 AFAIK,我不能使用 web.xml 配置文件中的所有设置,比如注册多个过滤器和 servlet,而且我不能使用我为在测试下运行的应用程序配置的相同 Spring 上下文定义模拟对象以及它们每次测试返回的内容。 我的每个 REST 资源都受 Spring Security 保护,它也没有加载 JerseyTest 框架,因为需要注册它的监听器。

请提供一些建议如何实现这一目标,或者使用其他测试框架来实现上述所有目标...

这是我的 junit 测试代码:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {MyResourceTest.MOCK_SPRING_APPLICATION_CONTEXT})
public class MyResourceTest extends JerseyTest {

    public static final String MOCK_SPRING_APPLICATION_CONTEXT = "classpath:spring/testApplicationContext.xml";

    @Override
    protected Application configure() {
        ResourceConfig resourceConfig = new MyResourceConfig();
        disable(TestProperties.LOG_TRAFFIC);
        disable(TestProperties.DUMP_ENTITY);
        resourceConfig.property("contextConfigLocation", MOCK_SPRING_APPLICATION_CONTEXT);
        return resourceConfig;
    }

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

    @Override
    protected DeploymentContext configureDeployment() {
        return ServletDeploymentContext
                .forServlet(new ServletContainer(new MyResourceConfig()))
                .addListener(MyContextLoaderListener.class) // Extends Spring's listener
                .addListener(RequestContextListener.class)
                .contextParam("contextConfigLocation", MOCK_SPRING_APPLICATION_CONTEXT)
                .build();
    }

    @Test
    @SqlGroup({
            @Sql(scripts = {"classpath:db_scripts/clean-up.sql", "classpath:db_scripts/init-db.sql"}),
            @Sql(scripts = "classpath:db_scripts/clean-up.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
    })
    public void shouldReceiveResourceTest() throws IOException {
        // Prepare request ...
        final MyResponse myResponse = target("/resource/1").request().post(myRequest, MyResponse.class);
        assertNotNull(myResponse);
    }

}

【问题讨论】:

  • 我通过添加 Spring Boot 并使用它的集成测试支持解决了这个问题。我只是按照这个例子link

标签: spring rest jersey-2.0 jersey-test-framework


【解决方案1】:

也许我的解决方案示例可以解决您的问题。我将它托管在 GitHub 上:

The better way to integrate JerseyTest with Spring

  • junit 测试类中没有从 JerseyTest 继承
  • 在 junit 测试类中不依赖 Jersey,只是纯粹的 jax-rs 依赖
  • 完美集成SpringJUnit4ClassRunner和@ContextConfiguration

【讨论】:

    【解决方案2】:

    您已经回退到 Spring Boot 选项,但是,让我与您分享一下我是如何在没有 Spring Boot 的情况下成功进行集成测试的。

    最棘手的部分是注册您的 web.xml 的内容,为了做到这一点,您需要按照以下方式设置您的服务器

    1. 使用 @Before 和 if 条件来确保为整个测试类设置一次容器,这样 spring 就不必为每个测试自动装配 bean
    2. 以编程方式创建 WebappContext 并注册您的 web.xml 中的所有内容,然后使用它的 deploy 方法将其传递给服务器实例(即 Grizzly 等)

    它是如何完成的?

    @Before
    public void setUp() throws Exception {
        if (server == null) {
            final ResourceConfig rc = new ResourceConfig(A.class, B.class);
    
            WebappContext ctx = new WebappContext() {};
            ctx.addContextInitParameter("contextConfigLocation", "classpath:applicationContext.xml");
    
            ctx.addListener("com.package.something.AServletContextListener");
    
            server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
                ctx.deploy(server);
            }
        }
    

    在我的 web.xml 中,我已经覆盖了 ContextListener 因此以下行

    ctx.addListener("..."); 
    

    您可以以类似的方式以编程方式创建一个 WebappContext,它只不过是您的 web.xml。它就像一个魅力。

    我已经回答了类似的问题,如果您想更详细地了解,这里是答案的link

    【讨论】:

      猜你喜欢
      • 2019-01-08
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      • 2015-01-06
      • 2017-05-24
      • 2020-02-25
      相关资源
      最近更新 更多