能否在含JNDI与Spring上下文的Jetty容器中运行TestNG集成测试?
答案:当然可以让TestNG测试在Jetty容器内运行,直接访问WAR的JNDI和Spring上下文
你完全不用局限于把Jetty只用来做HTTP接口测试——通过正确配置Maven、Failsafe和Jetty的联动,你的TestNG测试可以直接运行在Jetty容器的上下文里,共享WAR应用的所有JNDI资源和Spring上下文,不需要单独为测试重复配置这些环境。
下面是具体的实现步骤和注意事项:
1. 配置Maven插件联动,让Jetty随集成测试生命周期启动/停止
首先要确保Jetty在集成测试前启动,测试完成后自动停止,这需要在pom.xml里配置jetty-maven-plugin和maven-failsafe-plugin的生命周期绑定:
<build> <plugins> <!-- Jetty插件:在集成测试前启动,测试后停止 --> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.3.x</version> <!-- 替换成你的Jetty版本 --> <configuration> <jettyXml>path/to/your/jetty-jndi-config.xml</jettyXml> <!-- 指定你的JNDI配置文件 --> <webApp>path/to/your/war-file.war</webApp> <!-- 或者指向你的webapp源码目录 --> <stopPort>8099</stopPort> <!-- 自定义停止端口,避免冲突 --> <stopKey>stop-jetty</stopKey> </configuration> <executions> <execution> <id>start-jetty</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> </execution> <execution> <id>stop-jetty</id> <phase>post-integration-test</phase> <goals> <goal>stop</goal> </goals> </execution> </executions> </plugin> <!-- Failsafe插件:执行集成测试 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M7</version> <!-- 替换成最新稳定版 --> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <includes> <include>**/*IT.java</include> <!-- 约定集成测试类以IT结尾,可自定义 --> </includes> </configuration> </plugin> </plugins> </build>
2. 编写能访问容器资源的TestNG测试类
你的测试类需要运行在Jetty容器的上下文里,而不是独立的JVM进程中。这里有两种常用方式:
方式一:直接通过容器API访问JNDI和Spring上下文
测试类可以直接使用Jetty提供的容器上下文,或者Spring的Web上下文工具类来获取资源:
import org.testng.annotations.Test; import javax.naming.InitialContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import javax.servlet.ServletContext; public class MyIntegrationTestIT { // 类名以IT结尾,符合Failsafe约定 @Test public void testAccessJndiAndSpringContext() throws Exception { // 1. 访问JNDI资源(直接用InitialContext,Jetty已加载你的配置) InitialContext jndiCtx = new InitialContext(); MyJndiResource myResource = (MyJndiResource) jndiCtx.lookup("java:comp/env/jndi/myResource"); // 2. 访问Spring Web上下文 ServletContext servletContext = org.eclipse.jetty.servlet.ServletContextHandler.getCurrentServletContext(); WebApplicationContext springCtx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); MySpringBean myBean = springCtx.getBean(MySpringBean.class); // 执行你的测试断言 assert myResource != null : "JNDI资源未找到"; assert myBean != null : "Spring Bean未找到"; // 更多业务逻辑测试... } }
方式二:使用Spring Test框架简化上下文加载
如果你的项目用了Spring,可以借助spring-test模块的注解,更优雅地加载Spring上下文:
首先添加spring-test依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>你的Spring版本</version> <scope>test</scope> </dependency>
然后编写测试类:
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.Test; import javax.annotation.Resource; import javax.naming.InitialContext; @ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/applicationContext.xml"}) public class SpringIntegrationTestIT extends AbstractTestNGSpringContextTests { @Resource // 直接注入Spring Bean private MySpringBean mySpringBean; @Test public void testJndiAndSpring() throws Exception { // 访问JNDI资源 InitialContext jndiCtx = new InitialContext(); MyJndiResource myResource = (MyJndiResource) jndiCtx.lookup("java:comp/env/jndi/myResource"); // 测试Bean和JNDI资源 assert mySpringBean != null; assert myResource != null; } }
3. 关键注意事项
- 必须用Maven命令执行测试:不要直接在IDE里运行TestNG测试(除非你配置IDE的运行环境绑定Jetty启动),要执行
mvn verify命令,这样才会触发Jetty的启动、集成测试执行、Jetty停止的完整生命周期。 - 确保Jetty配置正确加载:
jetty-maven-plugin的<jettyXml>必须指向你的JNDI配置文件,这样Jetty启动时才会初始化这些JNDI资源。 - 测试类命名约定:默认Failsafe只会执行类名以
IT结尾的测试类,如果你想自定义,可以修改maven-failsafe-plugin的<includes>配置。
这样配置后,你的TestNG测试就会完全运行在Jetty容器环境中,和你的WAR应用共享同一个JNDI空间和Spring上下文,不需要为测试单独配置这些资源——Jetty的启动就是为了给测试提供完整的运行环境,而不只是用来做HTTP接口测试。
内容的提问来源于stack exchange,提问作者Gaponenko Andrei
相关产品推荐
相关产品推荐

