如何使用Jersey Test Framework启用CDI?

时间:2015-04-23 09:13:14

标签: unit-testing jersey testng cdi weld

我找到了How can I inject a data source dependency into a RESTful web service with Jersey (Test Framework)?,但我想我会问一些不同的问题。

这是@PostConstruct of abstract ancestors are not invoked

的后续问题

我写了一个JAX-RS库,我试图用Jersey Test Framework进行单元测试。

我好像HK2正确注射了。但我发现我的一些生命周期拦截器方法注释了@PostConstruct@PreDestroy没有被调用(或只有一些被调用)。

public class MyResource {

    @PostConstruct
    private void constructed() { // not invoked
    }

    @Inject
    private Some some; // injection works.
}

如何使用Jersey Test Framework启用CDI?我必须依赖什么样的文物?

这是我当前的依赖项。

<dependency>
  <groupId>javax.inject</groupId>
  <artifactId>javax.inject</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>javax.ws.rs</groupId>
  <artifactId>javax.ws.rs-api</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>org.glassfish.jersey.test-framework.providers</groupId>
  <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
  <scope>test</scope>
</dependency>

1 个答案:

答案 0 :(得分:3)

我找到了解决方案。

我添加了以下附加依赖项。

<dependency>
  <groupId>org.glassfish.jersey.ext.cdi</groupId>
  <artifactId>jersey-cdi1x</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.glassfish.jersey.ext.cdi</groupId>
  <artifactId>jersey-weld2-se</artifactId>
  <scope>test</scope>
</dependency>

现在Weld接管了HK2,我想。我不知道jersey-cdi1x-ban-custom-hk2-binding的用途。无论如何,我可以使用javax.enterprise:cdi-api中的标准注释。

public class MyProducer {

    @Produces @Some
    public MyType produceSome() {}

    public void disposeSome(@Disposes @Some MyType instance) {}
}

Weld的初始化代码补充道。

@Override
protected Application configure() {

    // this method works somewhat weirdly.
    // local variables including logger
    // is null in here
    // I have to start (and join) a thread
    // which initializes Weld and adds a shutdown hook

    final Thread thread = new Thread(() -> {
        final Weld weld = new Weld();
        weld.initialize();
        Runtime.getRuntime().addShutdownHook(
            new Thread(() -> weld.shutdown()));
    });
    thread.start();
    try {
        thread.join();
    } catch (final InterruptedException ie) {
        throw new RuntimeException(ie);
    }

    final ResourceConfig resourceConfig
        = new ResourceConfig(MyResource.class);

    resourceConfig.register(MyProducer.class);

    return resourceConfig;
}

注入每个点并调用所有生命周期方法。耶!!!

我不明白为什么我首先尝试使用线程。

@Override
protected Application configure() {

    final Weld weld = new Weld();
    weld.initialize();
    Runtime.getRuntime().addShutdownHook(new Thread(() -> weld.shutdown()));

    final ResourceConfig resourceConfig
        = new ResourceConfig(MyResource.class);

    resourceConfig.register(MyProducer.class);

    return resourceConfig;
}

由于我使用JerseyTestNg.ContainerPerClassTest,我失败了,至少在TestNG上,与@BeforeClass@AfterClass一起使用,因为configure()方法是从构造函数中调用的(间接)。< / p>

如果我切换到@BeforeMethod,我想我可以使用@AfterMethodJerseyTestNg.ContainerPerMethodTest来初始化/关闭Weld。

jersey-cdi1xjersey-weld2-se的传递依赖关系,因此可以省略。