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

@WebMvcTest测试含@Autowired构造方法的WebConfig时Bean缺失问题

问题分析与解决方案

这个问题的核心在于**@WebMvcTest是Spring的切片测试注解,它只会加载与Web层相关的最小化上下文**——比如你的OnlineDateController、Spring MVC的基础配置,但不会自动加载@ConfigurationProperties类,也不会自动处理配置类的依赖注入。你的WebConfig依赖OriginAllowedUrisProperties,但这个bean并没有被纳入测试上下文,所以抛出了依赖缺失的异常。

先规范配置类(可选但推荐)

首先,你的OriginAllowedUrisProperties注解有点冗余:@Configuration和@Component不需要同时使用,@ConfigurationProperties配合@Component就可以让Spring扫描并注册它,或者更规范的方式是用@EnableConfigurationProperties来显式注册:

// 修正后的配置属性类
@Component
@ConfigurationProperties(prefix = "origins")
public class OriginAllowedUrisProperties {
    private String[] allowedUris;
    
    // Getter和Setter
}

解决方案选择

方案1:加载真实的配置属性与WebConfig

如果你需要在测试中使用真实的CORS配置(比如从application-test.yml读取),可以在测试类中添加两个注解:

  • @EnableConfigurationProperties(OriginAllowedUrisProperties.class):告诉Spring在测试上下文里启用这个配置属性类
  • @Import(WebConfig.class):显式导入你的Web配置类

修改后的测试类:

@ExtendWith(SpringExtension.class)
@WebMvcTest(OnlineDateController.class)
@EnableConfigurationProperties(OriginAllowedUrisProperties.class)
@Import(WebConfig.class)
// 如果需要加载特定环境的配置文件,加上这个
@ActiveProfiles("test")
class TestOnlineDateController {
    @MockBean
    private OnlineDateService onlineDateService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetOnlineDate() throws Exception {
        when(onlineDateService.findOnlineDates()).thenReturn(
                Collections.singletonList(new OnlineDate()));
        mockMvc.perform(
                get("/onlineDates")
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(JSON_ONLINE_DATE_MATCHER)
                .andDo(print());
    }
}

方案2:Mock配置属性类(适合仅测试Controller逻辑)

如果你的测试不需要验证CORS逻辑,只是想测试Controller的接口响应,可以直接MockOriginAllowedUrisProperties,这样WebConfig就能被正常实例化:

@ExtendWith(SpringExtension.class)
@WebMvcTest(OnlineDateController.class)
class TestOnlineDateController {
    @MockBean
    private OnlineDateService onlineDateService;
    
    @MockBean
    private OriginAllowedUrisProperties originAllowedUrisProperties;

    @Autowired
    private MockMvc mockMvc;

    @BeforeEach
    void setup() {
        // 可选:设置mock的返回值,模拟配置的允许域名
        when(originAllowedUrisProperties.getAllowedUris())
            .thenReturn(new String[]{"http://localhost:3000"});
    }

    @Test
    void testGetOnlineDate() throws Exception {
        when(onlineDateService.findOnlineDates()).thenReturn(
                Collections.singletonList(new OnlineDate()));
        mockMvc.perform(
                get("/onlineDates")
                        .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(JSON_ONLINE_DATE_MATCHER)
                .andDo(print());
    }
}

为什么之前的尝试无效?

  • 仅添加@ContextConfiguration(classes = {WebConfig.class}):虽然加载了WebConfig,但它依赖的OriginAllowedUrisProperties并没有被Spring测试上下文注册——因为@WebMvcTest不会自动处理@ConfigurationProperties类。
  • 使用@Filter排除配置:这种操作反而可能移除了必要的上下文组件,没有从根本上解决依赖缺失的问题。

总结

  • 如果需要验证CORS相关的逻辑,选择方案1,加载真实的配置属性;
  • 如果只是测试Controller的业务接口响应,选择方案2,Mock依赖更简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:37:59