Я занимаюсь реорганизацией старого модуля, добавив CDI.Внутренняя зависимость не вводится (Weld + JavaSE)
Я заканчиваю с
public interface ApiFactory {
...
}
public class ApiFactorySp
implements ApiFactory {
@Inject
UrlProducer urlProducer; // <-- Does not get injected
...
}
и
public interface UrlProducer {
public String getUrl();
}
@Alternative
public class UrlProducerTest
implements UrlProducer {
@Override
public String getUrl() {
return "https://myTestEnv.mydomain/myWebApp";
}
}
Для тестирования, я создаю beans.xml
файл в META-INF
:
<beans
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
<alternatives>
<class>myOrg.myProject.myPackage.UrlProducerTest</class>
</alternatives>
</beans>
Чтобы проверить это, я делаю, как показано in this blog
public class WeldContext {
public static final WeldContext INSTANCE = new WeldContext();
private final Weld weld;
private final WeldContainer container;
private WeldContext() {
this.weld = new Weld();
this.container = weld.initialize();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
weld.shutdown();
}
});
}
public <T> T getBean(Class<T> type) {
return container.instance().select(type).get();
}
}
и
public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {
public WeldJUnit4Runner(Class<Object> clazz) throws InitializationError {
super(clazz);
}
@Override
protected Object createTest() {
final Class<?> test = getTestClass().getJavaClass();
return WeldContext.INSTANCE.getBean(test);
}
}
Теперь, когда я пытаюсь проверить логику, я
@RunWith(WeldJUnit4Runner.class)
public class MyTest {
@Inject
UrlProducer urlProducer;
@Inject
ApiFactory apiFactory;
@Test
public void test() {
apiFactory.doSomethingThatRequiresUrlProducer();
}
}
Когда я запускаю это, оба тестируемых атрибутов инъекционные, но я получаю NPE, потому что атрибуту urlProducer
внутри экземпляра apiFactory
не присвоено значение.
Почему Weld не распознает атрибут @Inject
внутри ApiFactory
?
JDK 7, Weld 2.2.10 Junit 4,12
UPDATE: После размещения вопроса, начал пробовать с более простым, новым проектом (только с двумя интерфейсами и три классов). Использование Weld «standalone» не решило проблему, используя CDI-Unit.
Затем я изменил свой первоначальный проект на использование CDI-Unit, но ничего не улучшил. После этого меняю инъекцию UrlProducerTest
в ApiFactory
из поля в конструктор (т. Е. Определяя конструктор @Inject ApiFactory(UrlProducer urlProducer)
). Я до сих пор не пробовал это решение с «автономным» Weld (то есть на завтра), но тем не менее меня все еще интересует, почему полевая инъекция не работает.
Вы уверены, что NPE не потому, что apiFactory не вводится? –
@ A.Panzer Да, я уверен, что «apiFactory» вводится. Но поскольку я собирался ответить, я думал, что я был уверен, потому что код, который использует 'UrlProducer', является ** в конструкторе **: - *>, и это вызывает исключение, которое должно быть выбрано во время создания экземпляра ... У меня будет чтобы проверить это завтра, но, возможно, вы хотите переписать свой ответ, чтобы принять это во внимание. – SJuan76