Cucumber集成Spring时Bean注入失败问题求助
问题:Cucumber Spring集成中Bean注入失败(NullPointerException)
我被困3天,距离实现功能仅一步之遥,十分困扰,希望有人能帮我解决问题。
我正在构建一个集成以下依赖的独立Jar包:
<dependency> <groupId>jakarta.inject</groupId> <artifactId>jakarta.inject-api</artifactId> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-spring</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency>
我的Glue类代码如下:
import io.cucumber.java.en.Given; import io.cucumber.spring.CucumberContextConfiguration; import jakarta.inject.Inject; import jakarta.inject.Named; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; @CucumberContextConfiguration @ContextConfiguration("classpath:spring.main.xml") public class MyStepDefinitions { private static final Logger LOGGER = LoggerFactory.getLogger(Dhis2StepDefinitions.class); @Inject @Named("testAtomicInt") @Autowired private AtomicInteger testCounter; @Given("I have {int} cukes in my belly") public void i_have_n_cukes_in_my_belly(int cukes) { testCounter.addAndGet(cukes); LOGGER.info("TEST: <{}> <{}> <{}>", cukes, testCounter, this); } }
你会看到我使用了多个注入注解,因为单独使用任何一个都无效。
我的spring.main.xml目前仅包含一个Bean:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="testAtomicInt" class="java.util.concurrent.atomic.AtomicInteger" /> </beans>
由于我们有大量spring.xml资源框架,无法仅依赖注解来实例化Bean。
我使用Cucumber标准主类io.cucumber.core.cli.Main启动测试,测试能运行并生成报告,且Spring已加载spring.main.xml并实例化testAtomicInt Bean,但注入始终失败,执行步骤时出现如下错误:
Given I have 1 cukes in my belly # org.rtsl.dhis2.cucumber.definitions.Dhis2StepDefinitions.i_have_n_cukes_in_my_belly(int) java.lang.NullPointerException: Cannot invoke "java.util.concurrent.atomic.AtomicInteger.addAndGet(int)" because "this.testCounter" is null at org.rtsl.dhis2.cucumber.definitions.Dhis2StepDefinitions.i_have_n_cukes_in_my_belly(Dhis2StepDefinitions.java:27) at ✽.I have 1 cukes in my belly(file:///Users/ademarcq/repo/rtsl_utils/rtsl_util/CommonUtils/Dhis2CucumberTestTool/./src/test/resources/local_tests/scenarios/dummy.feature:7)
我尝试了所有单独的注入注解,但均无效,请问我哪里出错了?
解决方案
1. 启用Spring注解驱动注入
XML配置默认不会自动处理@Autowired/@Inject这类注解,需要在spring.main.xml中添加<context:annotation-config/>标签来激活注解注入功能:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="testAtomicInt" class="java.util.concurrent.atomic.AtomicInteger" /> </beans>
2. 清理冗余注入注解
不要同时混用@Inject和@Autowired,选其一即可。针对按名称注入的场景,推荐两种写法:
- Spring原生注解组合:
@Autowired @Qualifier("testAtomicInt") private AtomicInteger testCounter; - JSR-250标准注解:
@Resource(name = "testAtomicInt") private AtomicInteger testCounter;
3. 确保Step类被Spring容器托管
给MyStepDefinitions添加@Component注解,同时在Spring配置中添加组件扫描,让Spring识别并管理这个类:
@Component @CucumberContextConfiguration @ContextConfiguration("classpath:spring.main.xml") public class MyStepDefinitions { // ... }
在spring.main.xml中添加扫描配置:
<context:component-scan base-package="org.rtsl.dhis2.cucumber.definitions"/>
4. 验证Cucumber启动参数
启动Cucumber时,必须指定正确的glue路径,确保Spring上下文配置类和Step定义类都被扫描到:
java -cp your-jar-file.jar io.cucumber.core.cli.Main --glue org.rtsl.dhis2.cucumber.definitions
5. 检查版本兼容性
确认cucumber-spring与Spring版本匹配:
- Cucumber 7.x 需搭配 Spring 5.3+ 或 Spring 6.x
- 如果使用Jakarta Inject(
jakarta.inject-api),需确保Spring版本支持Jakarta注解(Spring 6.x默认支持,Spring 5.x需额外适配)
内容的提问来源于stack exchange,提问作者Krohm
相关产品推荐
相关产品推荐

