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

使用JUnit参数化测试时MockMvc注入为空的问题排查

解决JUnit参数化测试中MockMvc注入为null的问题

方案一:改用JUnit 5参数化测试(推荐)

JUnit 5采用扩展模型,无需替换测试运行器,可与Spring Boot测试注解完美兼容,直接实现依赖注入+参数化测试。

修改测试类代码如下:

@SpringBootTest
@AutoConfigureMockMvc
class BadgeControllerIT {

    @Resource
    private MockMvc mockMvc;

    @ParameterizedTest
    @MethodSource("testInputs")
    void badgeControllerTests(MultiValueMap<String, String> params, String expectedBadgeAsSVG, ResultMatcher status) throws Exception {
        mockMvc
            .perform(
                get("/api/badge")
                    .queryParams(params)
                    .accept("image/svg+xml")
            )
            .andExpect(status)
            .andExpect(content().string(expectedBadgeAsSVG));
    }

    static Stream<Arguments> testInputs() {
        // 适配原有测试用例数组,转为JUnit 5的Arguments流
        return Arrays.stream(BadgeControllerTestsInputProvider.TEST_INPUTS)
                .map(Arguments::of);
    }
}

注意事项:

  • Spring Boot 2.2+版本的spring-boot-starter-test默认包含JUnit 5,无需额外引入依赖
  • 测试类无需添加@RunWith注解
  • 原BadgeControllerTestsInputProvider类可保持不变

方案二:JUnit 4下手动初始化Spring上下文

如果必须使用JUnit 4,可通过TestContextManager手动触发Spring上下文初始化和依赖注入,解决MockMvc/WebApplicationContext为null的问题:

修改测试类代码如下:

@RunWith(Parameterized.class)
@SpringBootTest
@AutoConfigureMockMvc
public class BadgeControllerIT {

    private TestContextManager testContextManager;

    @Resource
    private MockMvc mockMvc;

    private final MultiValueMap<String, String> params;
    private final String expectedBadgeAsSVG;
    private final ResultMatcher status;

    public BadgeControllerIT(MultiValueMap<String, String> params, String expectedBadgeAsSVG, ResultMatcher status) {
        this.params = params;
        this.expectedBadgeAsSVG = expectedBadgeAsSVG;
        this.status = status;
    }

    @Before
    public void setUp() throws Exception {
        // 手动初始化Spring测试上下文,触发依赖注入
        testContextManager = new TestContextManager(getClass());
        testContextManager.prepareTestInstance(this);
    }

    @Parameterized.Parameters
    public static Collection<Object[]> parameters() {
        return Arrays.asList(BadgeControllerTestsInputProvider.TEST_INPUTS);
    }

    @Test
    public void badgeControllerTests() throws Exception {
        mockMvc
            .perform(
                get("/api/badge")
                    .queryParams(params)
                    .accept("image/svg+xml")
            )
            .andExpect(status)
            .andExpect(content().string(expectedBadgeAsSVG));
    }
}

问题根源

JUnit 4的@RunWith注解只能指定一个测试运行器,当使用Parameterized.class时,会替换Spring的SpringJUnit4ClassRunner,导致Spring无法自动初始化上下文、完成依赖注入,最终MockMvc等Bean为null。

内容的提问来源于stack exchange,提问作者Soroush Shemshadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:05:19