2015-04-23 7 views
2

Я нашел How can I inject a data source dependency into a RESTful web service with Jersey (Test Framework)?, но я думаю, что я задам немного другой вопрос.Как включить CDI с тестовой платформой Джерси?

Это наблюдение вопрос @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. 
} 

Как включить 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> 

ответ

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() метод вызывается (косвенно) из конструктора.

Я думаю, что могу использовать @BeforeMethod и @AfterMethod для инициализации/выключения сварки, если я переключусь на JerseyTestNg.ContainerPerMethodTest.


jersey-cdi1x является транзитивной зависимостью от jersey-weld2-se так что он может быть опущен.

+0

Просто интересно, попробовали ли вы '@ BeforeClass' и' @ AfterClass' аннотированные методы для инициализации и выключения сварки? Поскольку это тестовый класс, кажется подходящим –

+0

@peeskillet Я нашел 'configure()', по-видимому, косвенно вызван из конструктора класса 'JerseyTest'. Вот почему событие «logger» не используется в этом методе. –

+0

Что я имел в виду, так это то, что тесты JUnit предлагают аннотации '@ BeforeClass' и' @ AfterClass', которые можно разместить на произвольных статических методах в вашем тестовом классе. Первый будет вызываться до начала тестирования, а второй - после.Вместо потоковой передачи я просто задавался вопросом, будет ли работать статическое поле Weld, запустить его в методе before и закрыть его после метода after. –