Cucumber与Spring Autowiring整合失效问题求助
解决Cucumber + Spring Boot中@Autowired注入NullPointerException的问题
嘿,我来帮你搞定这个Cucumber和Spring Boot整合的问题!你遇到的NullPointerException其实是因为Cucumber没有正确关联Spring的上下文,导致Spring容器没初始化,@Autowired的组件自然没法被注入进来。下面我给你一套经过验证的完整解决方案,照着来就能解决问题:
问题核心原因
你的步骤类没有被纳入Spring上下文管理,Cucumber默认不会自动加载Spring容器,必须通过特定的配置让Cucumber识别并初始化Spring测试上下文,这样依赖注入才能正常工作。
完整可行解决方案
1. 调整Maven pom.xml依赖配置
首先确保Cucumber和Spring Boot的版本兼容,避免版本冲突,下面是经过验证的依赖配置:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.cucumber</groupId> <artifactId>cucumberdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <cucumber.version>5.7.0</cucumber.version> <spring.version>5.2.5.RELEASE</spring.version> <spring-boot.version>2.2.6.RELEASE</spring.version> <junit-platform.version>1.6.2</junit-platform.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-core</artifactId> <version>${cucumber.version}</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>${cucumber.version}</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java8</artifactId> <version>${cucumber.version}</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-spring</artifactId> <version>${cucumber.version}</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit</artifactId> <version>${cucumber.version}</version> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>${cucumber.version}</version> </dependency> <!-- Spring doesn't include the right version for surefire to pickup TODO: Remove once the surefire or spring is upgraded --> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-commons</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2. 创建Cucumber上下文配置类
这个类是核心!必须加上@CucumberContextConfiguration注解,让Cucumber识别并加载Spring Boot的测试上下文:
package com.cucumber.test; import org.springframework.boot.test.context.SpringBootTest; import io.cucumber.java.Before; import io.cucumber.spring.CucumberContextConfiguration; @CucumberContextConfiguration @SpringBootTest(classes = SpringBootCucumberApplication.class) // 指定你的Spring Boot主启动类 public class CucumberTestContextConfiguration { @Before public void setup_cucumber_spring_context(){ // 空方法即可,目的是让Cucumber识别这个类作为glue类,从而加载Spring上下文 } }
3. 编写Cucumber测试启动类
这是JUnit的入口类,用来运行Cucumber测试,要指定feature文件路径和glue包(必须包含上下文配置类和步骤类的包):
package com.cucumber.test; import org.junit.runner.RunWith; import io.cucumber.junit.Cucumber; import io.cucumber.junit.CucumberOptions; @RunWith(Cucumber.class) @CucumberOptions( features = "src/test/resources/features", plugin = {"pretty", "html:target/cucumber/reports"}, glue = {"com.cucumber.test"} ) public class CucumberFunctionalTest { }
4. 编写Spring组件类
这是你要注入的业务组件,加上@Component让Spring管理:
package com.cucumber.test; import org.springframework.stereotype.Component; @Component public class DataUtil { public void getData() { System.out.println( "Extract data .."); } }
5. 编写Cucumber步骤类
步骤类不需要加@Component,Cucumber会自动将其纳入Spring上下文管理,直接使用@Autowired注入即可:
package com.cucumber.test; import org.springframework.beans.factory.annotation.Autowired; import io.cucumber.datatable.DataTable; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; public class TestStep { @Autowired private DataUtil dataUtil; @Given("all tables are empty") public void all_tables_are_empty() { System.out.println("1"); } @When("data provided") public void data_provided(DataTable table) { dataUtil.getData(); // 这里不会再出现NullPointerException System.out.println("2"); } @Then("tables are populated with provided data") public void tables_are_populated_with_provided_data() { System.out.println("3"); } }
6. Spring Boot主启动类
确保你的主启动类加上@SpringBootApplication,让Spring自动扫描组件:
package com.cucumber.test; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.servlet.config.annotation.EnableWebMvc; @SpringBootApplication @EnableWebMvc public class SpringBootCucumberApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCucumberApplication.class, args); } }
7. 编写Cucumber Feature文件
放在src/test/resources/features目录下:
Feature: Test Data Load Scenario: Verify the Test data Given all tables are empty When data provided Then tables are populated with provided data
关键注意事项
- 版本匹配:一定要确保Cucumber和Spring Boot的版本兼容,不同版本的Cucumber对Spring的支持逻辑可能有差异,本文用的5.7.0和Spring Boot 2.2.x是经过验证的组合。
- Glue包配置:
@CucumberOptions中的glue必须包含上下文配置类和步骤类所在的包,否则Cucumber找不到Spring上下文配置。 - @CucumberContextConfiguration注解:这个注解是Cucumber识别Spring上下文的关键,之前你没加这个注解,所以配置了
@SpringBootTest也没用。 - 步骤类无需@Component:Cucumber会自动管理步骤类,不需要额外加Spring的组件注解。
内容的提问来源于stack exchange,提问作者Muthu
相关产品推荐
相关产品推荐

