使用maven-failsafe-plugin时,如何向JUnit集成测试注入TomEE部署上下文?
嘿,刚好我对Arquillian+TomEE的集成测试很熟,这就给你一步步拆解怎么实现跨JVM的上下文和组件注入!
1. 先搞定Maven依赖
首先得把Arquillian的核心依赖、TomEE远程容器适配器,还有JUnit集成包加到你的pom.xml里。这些依赖能让测试JVM和TomEE JVM建立通信,实现远程注入:
<dependencies> <!-- Arquillian Core --> <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <version>1.6.0.Final</version> <scope>test</scope> </dependency> <!-- TomEE Remote Container Adapter --> <dependency> <groupId>org.apache.tomee</groupId> <artifactId>arquillian-tomee-remote</artifactId> <version>8.0.12</version> <!-- 换成你实际使用的TomEE版本 --> <scope>test</scope> </dependency> <!-- 注入CDI/EJB所需的API依赖 --> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <version>2.0.SP1</version> <scope>test</scope> </dependency> </dependencies>
2. 配置Arquillian连接到你的TomEE实例
在src/test/resources下创建arquillian.xml,告诉Arquillian怎么连接到你已经启动的TomEE服务器(对应你现有流程的步骤d):
<arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> <container qualifier="tomee-remote" default="true"> <configuration> <!-- TomEE的HTTP端口,默认8080 --> <property name="httpPort">8080</property> <!-- TomEE的停止端口,默认8005 --> <property name="stopPort">8005</property> <!-- TomEE管理员账号密码 --> <property name="username">admin</property> <property name="password">admin</property> <!-- 指定你已经部署的WAR包路径 --> <property name="deployable">target/your-app.war</property> </configuration> </container> </arquillian>
3. 改造你的集成测试类
现在就可以在测试类里用Arquillian的注解来注入上下文或者Java EE组件了,举个实际的例子:
import org.jboss.arquillian.container.test.api.ArquillianResource; import org.jboss.arquillian.junit.Arquillian; import javax.inject.Inject; import javax.servlet.ServletContext; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(Arquillian.class) public class AppIntegrationIT { // 注入TomEE上部署应用的Servlet上下文 @ArquillianResource private ServletContext servletContext; // 注入你WAR包中定义的CDI Bean @Inject private UserService userService; @Test public void testContextAndBeanInjection() { // 验证上下文注入成功 assert servletContext != null; System.out.println("当前应用上下文根:" + servletContext.getContextPath()); // 调用远程CDI Bean的方法,验证注入有效性 assert userService != null; String userName = userService.getUserNameById(1); assert "testUser".equals(userName); } }
4. 适配你的现有Maven Profile
因为你已经有一套安装、部署、启动TomEE的流程,只需要确保两点:
- 执行failsafe插件的测试任务之前,TomEE已经完全启动且WAR包部署完成
- 测试类的命名符合failsafe的默认规则(比如以
IT结尾)
如果你觉得手动管理TomEE太繁琐,也可以让Arquillian接管安装、部署、启动、停止的全流程——只需要把容器适配器换成arquillian-tomee-embedded或者arquillian-tomee-managed,调整arquillian.xml的配置即可,这样就能删掉Profile里的步骤a-d,让流程更自动化。
关键原理说明
Arquillian在跨JVM场景下,会通过TomEE的远程管理API建立测试JVM和TomEE JVM的通信通道。当你用@Inject或者@ArquillianResource注解时,Arquillian会在TomEE端查找对应的组件,然后通过序列化+远程调用的方式把组件的代理对象传递到测试JVM,让你能像调用本地对象一样使用远程的Java EE组件。
内容的提问来源于stack exchange,提问作者user1717068

