You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:26:49