0

我正在开发一个使用 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);
    }

}
4

2 回答 2

0

您已经回退到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。它就像一个魅力。

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

于 2016-10-01T17:13:21.833 回答
0

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

将 JerseyTest 与 Spring 集成的更好方法

  • junit 测试类中没有从 JerseyTest 继承
  • junit 测试类中没有对 Jersey 的依赖,只是纯粹的 jax-rs 依赖
  • 完美集成 SpringJUnit4ClassRunner 和 @ContextConfiguration
于 2016-08-03T01:35:53.027 回答