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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:02:34