为什么我的拦截器在 Weld SE 单元测试中失败?
Why does my Interceptor Fail in a Weld SE unit test?
我有一个拦截器,当我在 Web 应用程序中使用它时,它似乎被 JBoss (EAP 6.4) 正确加载,但当我在焊接中使用相同的 beans.xml 时被拒绝-se 上下文。
package com.Whosebug;
import javax.enterprise.context.Dependent;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@BindingAnnotation
@Dependent
public class InterceptorTest {
@AroundInvoke
public Object crypto(InvocationContext invocationContext) throws Exception {
return null;
}
}
还有一个测试:
package com.Whosebug;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.junit.Before;
import org.junit.Test;
public class InterceptorTestTest {
WeldContainer container;
@Before
public void setup(){
Weld weld = new Weld();
container = weld.initialize();
}
@Test
public void crypto() throws Exception {
}
}
当我运行测试时:
[main] INFO org.jboss.weld.Version - WELD-000900 1.1.28 (Final)
[main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
org.jboss.weld.exceptions.DeploymentException: WELD-001417 Enabled interceptor class <class>com.Whosebug.InterceptorTest</class> in file:/Users/pstanden/IdeaProjects/crypto/test/target/test-classes/META-INF/beans.xml@7 is neither annotated @Interceptor nor registered through a portable extension
at org.jboss.weld.bootstrap.Validator.validateEnabledInterceptorClasses(Validator.java:503)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:373)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
at org.jboss.weld.bootstrap.api.helpers.ForwardingBootstrap.validateBeans(ForwardingBootstrap.java:85)
我真的搞不清楚我应该添加或删除什么,以及为什么 Weld org.jboss.weld.se:weld-se:1.1.28.Final 似乎对同一版本的焊接 JBoss?
编辑:
我的 beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.Whosebug.InterceptorTest</class>
</interceptors>
</beans>
再次编辑我的pom:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.Whosebug</groupId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>test</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>1.1.28.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.javaee</groupId>
<artifactId>javaee</artifactId>
<version>6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
好的,成功重现了您的问题并了解您在做什么。作为记录,它对我有用,因为我 运行 它是主要方法,而不是测试。
这里的问题是您使用的是纯 JUnit,而您的 类 在 src/test
- Weld 不会拾取它们,或者更确切地说,不会扫描它们并将它们识别为beans/interceptors 等。因此,您的拦截器将不会被发现并且 beans.xml
中的定义将无效导致您 see.This 是 JUnit 的一个已知问题,因为它不足以测试 CDI。
要解决此问题,您可以将这些 类 放入 src/main
,它们应该会被正确拾取。但很有可能,迟早你会遇到类似的问题。
要真正解决这个问题,我建议您使用 Arquillian
作为框架并使用 Arquillian-container-Weld
作为容器来编写测试 运行s。请注意,这仍然是 SE(尽管 Arquillian 也用于 EE 测试)。它允许您创建一个测试存档并将您认为有价值的任何内容放入其中,Weld 将全部收集起来。
为了激发自己的灵感,您可以看一下 Weld testsuite,SE 测试中使用了相同的东西。这是一个这样的测试 link。
如需帮助,您可以使用:
this.weld = new Weld();
weld.addBeanClass(AInterceptor.class);
weld.addBeanClass(BInterceptor.class);
weld.enableInterceptors(AInterceptor.class,BInterceptor.class);
我有一个拦截器,当我在 Web 应用程序中使用它时,它似乎被 JBoss (EAP 6.4) 正确加载,但当我在焊接中使用相同的 beans.xml 时被拒绝-se 上下文。
package com.Whosebug;
import javax.enterprise.context.Dependent;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@BindingAnnotation
@Dependent
public class InterceptorTest {
@AroundInvoke
public Object crypto(InvocationContext invocationContext) throws Exception {
return null;
}
}
还有一个测试:
package com.Whosebug;
import org.jboss.weld.environment.se.Weld;
import org.jboss.weld.environment.se.WeldContainer;
import org.junit.Before;
import org.junit.Test;
public class InterceptorTestTest {
WeldContainer container;
@Before
public void setup(){
Weld weld = new Weld();
container = weld.initialize();
}
@Test
public void crypto() throws Exception {
}
}
当我运行测试时:
[main] INFO org.jboss.weld.Version - WELD-000900 1.1.28 (Final)
[main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
org.jboss.weld.exceptions.DeploymentException: WELD-001417 Enabled interceptor class <class>com.Whosebug.InterceptorTest</class> in file:/Users/pstanden/IdeaProjects/crypto/test/target/test-classes/META-INF/beans.xml@7 is neither annotated @Interceptor nor registered through a portable extension
at org.jboss.weld.bootstrap.Validator.validateEnabledInterceptorClasses(Validator.java:503)
at org.jboss.weld.bootstrap.Validator.validateDeployment(Validator.java:373)
at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:379)
at org.jboss.weld.bootstrap.api.helpers.ForwardingBootstrap.validateBeans(ForwardingBootstrap.java:85)
我真的搞不清楚我应该添加或删除什么,以及为什么 Weld org.jboss.weld.se:weld-se:1.1.28.Final 似乎对同一版本的焊接 JBoss?
编辑: 我的 beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.Whosebug.InterceptorTest</class>
</interceptors>
</beans>
再次编辑我的pom:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.Whosebug</groupId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<modelVersion>4.0.0</modelVersion>
<artifactId>test</artifactId>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>1.1.28.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.javaee</groupId>
<artifactId>javaee</artifactId>
<version>6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
好的,成功重现了您的问题并了解您在做什么。作为记录,它对我有用,因为我 运行 它是主要方法,而不是测试。
这里的问题是您使用的是纯 JUnit,而您的 类 在 src/test
- Weld 不会拾取它们,或者更确切地说,不会扫描它们并将它们识别为beans/interceptors 等。因此,您的拦截器将不会被发现并且 beans.xml
中的定义将无效导致您 see.This 是 JUnit 的一个已知问题,因为它不足以测试 CDI。
要解决此问题,您可以将这些 类 放入 src/main
,它们应该会被正确拾取。但很有可能,迟早你会遇到类似的问题。
要真正解决这个问题,我建议您使用 Arquillian
作为框架并使用 Arquillian-container-Weld
作为容器来编写测试 运行s。请注意,这仍然是 SE(尽管 Arquillian 也用于 EE 测试)。它允许您创建一个测试存档并将您认为有价值的任何内容放入其中,Weld 将全部收集起来。
为了激发自己的灵感,您可以看一下 Weld testsuite,SE 测试中使用了相同的东西。这是一个这样的测试 link。
如需帮助,您可以使用:
this.weld = new Weld();
weld.addBeanClass(AInterceptor.class);
weld.addBeanClass(BInterceptor.class);
weld.enableInterceptors(AInterceptor.class,BInterceptor.class);