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

Cucumber StepDef执行时ResultActions抛出NullPointerException求助

解决Cucumber StepDef中调用MockMvc时的NullPointerException问题

你的NullPointerException根源在于JUnit的@BeforeClass注解在Cucumber测试生命周期中不会被执行,导致mockMvc始终是null,调用mockMvc.perform()时触发空指针异常。另外,你混用了JUnit和Cucumber的测试生命周期注解,这是核心问题。

问题分析

  1. 你在PersonStepDefs中使用了JUnit的@BeforeClass,但Cucumber测试是由RunMvcTest中的Cucumber.class runner驱动的,Cucumber不会识别JUnit的@BeforeClass注解,所以setup()方法根本没执行,mockMvc一直是null。
  2. 虽然你给mockMvc加了@Autowired,但如果Spring上下文没有正确初始化MockMvc实例,这个注入也会失败。

修复步骤

1. 替换JUnit钩子为Cucumber钩子

把@BeforeClass替换为Cucumber的@Before注解(注意导入的是io.cucumber.java.Before,不是JUnit的),确保在每个Scenario执行前初始化MockMvc:

修改PersonStepDefs.java中的setup方法:

// 替换原来的@BeforeClass
import io.cucumber.java.Before;

// ...其他代码...

@Before
public void setup() {
    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}

2. 移除不必要的@Autowired MockMvc

既然我们手动通过WebApplicationContext构建MockMvc,就不需要再注入MockMvc了,可以把@Autowired private volatile MockMvc mockMvc;这一行删掉,避免冲突:

// 删掉这一行
// @Autowired
// private volatile MockMvc mockMvc;

private MockMvc mockMvc; // 直接声明即可

3. 验证Spring上下文配置

确保RunMvcTest中的@ContextConfiguration(classes = V2Application.class)指向正确的应用启动类,这样Cucumber才能正确加载Spring Web上下文。

修复后的完整PersonStepDefs.java

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import io.cucumber.java.Before;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

@WebAppConfiguration
@Transactional
/**
 * Person Step Definition class to execute Scenario contained in Person.feature
 * @author Lewis Jones
 * */
public class PersonStepDefs {

	@Autowired
	private volatile WebApplicationContext wac;

	private MockMvc mockMvc;

	private ResultActions result;

	/**
	 * Runs before every scenario to initialize MockMvc
	 */
	@Before
	public void setup() {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
	}

	@When("I add a new Person using POST at {string} with JSON:")
	public void i_add_a_new_Person_using_POST_at_with_JSON(String request, String json) throws Exception {
		result = mockMvc.perform(post(request).contentType(MediaType.APPLICATION_JSON)
				.content(json.getBytes()));
	}

	@Then("the response code should be {int}")
	public void the_response_code_should_be(Integer responseCode) throws Exception {
		result.andExpect(status().is(responseCode));
	}
}

额外建议

  • 不需要在StepDef类上添加@RunWith(SpringJUnit4ClassRunner.class),因为Cucumber测试的runner已经在RunMvcTest中指定了。
  • 如果你想更简洁,可以直接使用@AutoConfigureMockMvc注解来自动注入MockMvc,不需要手动构建,但前提是Spring上下文正确加载。

内容的提问来源于stack exchange,提问作者L Jones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:37:39